www.gusucode.com > A benchmark software for MSPC工具箱matlab程序 > A benchmark software for MSPC/MSPC_main.m

    function varargout = MSPC_main(varargin)
% MSPC_MAIN M-file for MSPC_main.fig
%      MSPC_MAIN, by itself, creates a new MSPC_MAIN or raises the existing
%      singleton*.
%
%      H = MSPC_MAIN returns the handle to a new MSPC_MAIN or the handle to
%      the existing singleton*.
%
%      MSPC_MAIN('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in MSPC_MAIN.M with the given input arguments.
%
%      MSPC_MAIN('Property','Value',...) creates a new MSPC_MAIN or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before MSPC_main_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to MSPC_main_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help MSPC_main

% Last Modified by GUIDE v2.5 04-Apr-2017 12:04:33

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @MSPC_main_OpeningFcn, ...
                   'gui_OutputFcn',  @MSPC_main_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before MSPC_main is made visible.
function MSPC_main_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to MSPC_main (see VARARGIN)

% Choose default command line output for MSPC_main
handles.output = hObject;
handles.DataSourceName = [];

% Update handles structure
guidata(hObject, handles);

% m-file path: this allows to open the Simulink model although the current
% path in Matlab is not the path where the model is in
global mPath
[mPath,mName,mExt] = fileparts(mfilename('fullpath'));

% Path of the current project file
global projectPath
projectPath = '';

% Create default values ...
CreateDefaultValues(hObject, handles);

UpdateTreeView(hObject, eventdata, handles,'openwindow');

% UIWAIT makes MSPC_main wait for user response (see UIRESUME)
% uiwait(handles.MSPC_main);


% --- Outputs from this function are returned to the command line.
function varargout = MSPC_main_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;



function txtSampleTime_Callback(hObject, eventdata, handles)
% hObject    handle to txtSampleTime (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtSampleTime as text
%        str2double(get(hObject,'String')) returns contents of txtSampleTime as a double
SaveParam(hObject,handles,1);



% --- Executes during object creation, after setting all properties.
function txtSampleTime_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtSampleTime (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtSimTime_Callback(hObject, eventdata, handles)
% hObject    handle to txtSimTime (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtSimTime as text
%        str2double(get(hObject,'String')) returns contents of txtSimTime as a double
SaveParam(hObject,handles,1);



% --- Executes during object creation, after setting all properties.
function txtSimTime_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtSimTime (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in chkNoise.
function chkNoise_Callback(hObject, eventdata, handles)
% hObject    handle to chkNoise (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkNoise
SaveParam(hObject,handles,1);




function txtChangeRatio_z_Callback(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtChangeRatio_z as text
%        str2double(get(hObject,'String')) returns contents of txtChangeRatio_z as a double
SaveParam(hObject,handles,1);



% --- Executes during object creation, after setting all properties.
function txtChangeRatio_z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtChangeRatio_T_Callback(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtChangeRatio_T as text
%        str2double(get(hObject,'String')) returns contents of txtChangeRatio_T as a double
SaveParam(hObject,handles,1);



% --- Executes during object creation, after setting all properties.
function txtChangeRatio_T_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtChangeRatio_F_Callback(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtChangeRatio_F as text
%        str2double(get(hObject,'String')) returns contents of txtChangeRatio_F as a double
SaveParam(hObject,handles,1);



% --- Executes during object creation, after setting all properties.
function txtChangeRatio_F_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtDisturbanceTime_z_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceTime_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceTime_z as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceTime_z as a double
SaveParam(hObject,handles,2);


% --- Executes during object creation, after setting all properties.
function txtDisturbanceTime_z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceTime_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in cmbDisturbanceType_z.
function cmbDisturbanceType_z_Callback(hObject, eventdata, handles)
% hObject    handle to cmbDisturbanceType_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
SaveParam(hObject,handles,2);

% Hints: contents = cellstr(get(hObject,'String')) returns cmbDisturbanceType_z contents as cell array
%        contents{get(hObject,'Value')} returns selected item from cmbDisturbanceType_z
if get(handles.chkActDisturb_z,'value')==1
    switch get(handles.cmbDisturbanceType_z,'value')
        case {1,2} %spike, ramp
            sActive = 'off';
        case 3 %pulse
            sActive = 'on';
    end
else
    sActive = 'off';
end
set(handles.txtPulseDuration_z,'enable',sActive);



% --- Executes during object creation, after setting all properties.
function cmbDisturbanceType_z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to cmbDisturbanceType_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function mnuFile_Callback(hObject, eventdata, handles)
% hObject    handle to mnuFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)



% --------------------------------------------------------------------
function mnuPhaseIRun_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIRun (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

RunSimulation(hObject,handles);


% --------------------------------------------------------------------
function mnuPhaseIPlotResults_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIPlotResults (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

PlotResults(handles);


% --------------------------------------------------------------------
function mnuPhaseIPCA_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIPCA (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function mnuOpen_Callback(hObject, eventdata, handles)
% hObject    handle to mnuOpen (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Loads a previously saved simulation...
% d = dir('*.cdb');
% sFileList = {d.name};
% if isempty(sFileList)
%     msgbox('There are no previously saved simulations','Open','warn');
% else
%     [s,v] = listdlg('PromptString','Select a file:',...
%                     'SelectionMode','single',...
%                     'ListString',sFileList);
%     if v==1
%         handles.FileName = char(sFileList(s));
%         UpdateTreeView(hObject, eventdata, handles,'open');
%     end
% end

global projectPath

[cdbFileName,cdbPathName] = uigetfile({'*.cdb','Distillation benchmark (*.cdb)'}, ...
                                      'Open a project');
if ~isequal(cdbFileName,0)
    handles.DataSourceName = [];
    handles.Dataset = [];
    handles.BenchmarkName = [];
    handles.BenchmarkDesc = [];
    handles = ClearResults(hObject,handles);
    handles.FileName = fullfile(cdbPathName, cdbFileName);
    projectPath = cdbPathName;
    UpdateTreeView(hObject, eventdata, handles,'open');
end

                                        

% --------------------------------------------------------------------
function mnuSave_Callback(hObject, eventdata, handles)
% hObject    handle to mnuSave (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
save_results(hObject,handles,'yes');

% --------------------------------------------------------------------
function mnuSaveAs_Callback(hObject, eventdata, handles)
% hObject    handle to mnuSaveAs (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
save_results(hObject,handles,'yes',1);

% --------------------------------------------------------------------
function mnuExit_Callback(hObject, eventdata, handles)
% hObject    handle to mnuExit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close(gcbf);


function PlotResults(handles)
[phase,sType,sTestId] = GetPhase(handles);
if phase==1
    if ~check_errors('handles', handles, 'sType', 'phaseI_data')
        return;
    end
    sTitle = 'Phase I. Simulation results.';
    Results = handles.P1_SimResults;
else
    if ~check_errors('handles', handles, 'sType', 'phaseII_data', 'sTestId', sTestId)
        return;
    end
    sTitle = ['Phase II. Test ' sTestId '. Simulation results.'];
    sSimResults = ['P2_SimResults_' sTestId];
    sEval = ['Results = handles.' sSimResults ';'];
    eval(sEval);
end
figure;
set(gcf, 'Name', sTitle);
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure. 
subplot(3,4,1);
plot(Results.t,Results.zF);
axis([Results.t(1) Results.t(end) min(Results.zF) max(Results.zF)]);
title('z_F');
subplot(3,4,2)
plot(Results.t,Results.TF);
axis([Results.t(1) Results.t(end) min(Results.TF) max(Results.TF)]);
title('T_F');
subplot(3,4,3)
plot(Results.t,Results.FV);
axis([Results.t(1) Results.t(end) min(Results.FV) max(Results.FV)]);
title('F');
subplot(3,4,5);
plot(Results.t,Results.L);
axis([Results.t(1) Results.t(end) min(Results.L) max(Results.L)]);
title('L');
subplot(3,4,6);
plot(Results.t,Results.D);
axis([Results.t(1) Results.t(end) min(Results.D) max(Results.D)]);
title('D');
subplot(3,4,7);
plot(Results.t,Results.MD);
axis([Results.t(1) Results.t(end) min(Results.MD) max(Results.MD)]);
title('M_D');
subplot(3,4,9);
plot(Results.t,Results.V);
axis([Results.t(1) Results.t(end) min(Results.V) max(Results.V)]);
title('V');
subplot(3,4,10);
plot(Results.t,Results.B);
axis([Results.t(1) Results.t(end) min(Results.B) max(Results.B)]);
title('B');
subplot(3,4,11);
plot(Results.t,Results.MB);
axis([Results.t(1) Results.t(end) min(Results.MB) max(Results.MB)]);
title('M_B');
subplot(3,4,12);
plot(Results.t,Results.xB);
axis([Results.t(1) Results.t(end) min(Results.xB) max(Results.xB)]);
title('x_B');
subplot(3,4,8);
plot(Results.t,Results.yD);
axis([Results.t(1) Results.t(end) min(Results.yD) max(Results.yD)]);
title('y_D');


function save_results(hObject,handles,message,bSaveAs)
% set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback
% Save param, phase I results and phase II results to mat file in the app directory
global projectPath

if ~exist('bSaveAs', 'var')
    bSaveAs = 0;
end

P1_SimParam = handles.P1_SimParam;
sName = '';
if isfield(P1_SimParam,'BenchmarkName')
    sName = fullfile(projectPath,P1_SimParam.BenchmarkName);
end
if exist(sName, 'file') && bSaveAs==0
    vSave = 'save(sName,''-append'',''P1_SimParam''';
else
    % Ask for a file location
    [cdbFileName,cdbPathName] = uiputfile({'*.cdb','Distillation benchmark (*.cdb)'}, ...
                                          'Save project', ...
                                          P1_SimParam.BenchmarkName);
    if isequal(cdbFileName,0) || isequal(cdbPathName,0)
        exit function;
    end
    set(handles.txtBenchmarkName,'string',cdbFileName);
    handles.P1_SimParam.BenchmarkName = cdbFileName;
    P1_SimParam.BenchmarkName = cdbFileName;
    guidata(hObject, handles);
    projectPath = cdbPathName;
    sName = fullfile(projectPath,cdbFileName);
    vSave = 'save(sName,''P1_SimParam''';
end
if isfield(handles,'P1_SimResults');
    P1_SimResults = handles.P1_SimResults;
    vSave = [vSave ',''P1_SimResults'''];
end
if isfield(handles,'P1_PCAResults');
    P1_PCAResults = handles.P1_PCAResults;
    vSave = [vSave ',''P1_PCAResults'''];
end
NumberOfTests = handles.NumberOfTests;
vSave = [vSave ',''NumberOfTests'''];
for idSim=1:NumberOfTests
    sSimParam = ['P2_SimParam_' sprintf('%02d',idSim)];
    if isfield(handles,sSimParam);
        sEval = [sSimParam ' = handles.' sSimParam ';'];
        eval(sEval);
        vSave = [vSave ',''' sSimParam ''''];
    end
    sSimResults = ['P2_SimResults_' sprintf('%02d',idSim)];
    if isfield(handles,sSimResults);
        sEval = [sSimResults ' = handles.' sSimResults ';'];
        eval(sEval);
        vSave = [vSave ',''' sSimResults ''''];
    end
    sPCAResults = ['P2_PCAResults_' sprintf('%02d',idSim)];
    if isfield(handles,sPCAResults);
        sEval = [sPCAResults ' = handles.' sPCAResults ';'];
        eval(sEval);
        vSave = [vSave ',''' sPCAResults ''''];
    end
end
% For external data ...
if isfield(handles,'DataSourceName');
    DataSourceName = handles.DataSourceName;
    vSave = [vSave ',''DataSourceName'''];
end
if isfield(handles,'Dataset');
    Dataset = handles.Dataset;
    vSave = [vSave ',''Dataset'''];
end
vSave = [vSave ');'];
eval(vSave);
if strcmp(message,'yes')
    msgbox('Process complete','Save');
end



function ExportToExcel(sName,sSheet,Results)
% Exports P1_SimResults to Excel file in the app directory
x='x2';
for k=3:40
    x=char(x,strcat('x',num2str(k)));
end
x=cellstr(x);
x=x';
ts='T1';
for k=2:41
    ts=char(ts,strcat('T',num2str(k)));
end
ts=cellstr(ts);
ts=ts';
tdesc='bottoms temp (ºC)';
for k=1:39
    tdesc=char(tdesc,strcat('tray',' ',num2str(k), ' temp (ºC)'));
end
tdesc=char(tdesc,'distillate temp (ºC)');
tdesc=cellstr(tdesc);
tdesc=tdesc';
xlswrite(sName,{'t' 'F' 'zF' 'TF' 'yD' 'xB' 'MD' 'MB' 'L' 'V' 'D' 'B' ts{:}},sSheet,'A1');
xlswrite(sName,{'time (min)' 'feed volumetric flow (L/h)' 'feed composition' ...
                'feed temperature (ºC)' 'distillate composition' 'bottoms composition' ...
                'condenser holdup (kmol)' 'reboiler holdup (kmol)' 'reflux flow (L/h)' 'boilup flow (L/h)' ...
                'distillate flow (L/h)' 'bottoms flow (L/h)' tdesc{:} },sSheet,'A2');
xlswrite(sName,[Results.t  Results.FV Results.zF Results.TF Results.yD Results.xB ...
                Results.MD Results.MB Results.L Results.V Results.D Results.B ...
                Results.Temp(:,1:41)],sSheet,'A3');


function cMat = ExportToMatlab(Results)
% Exports P1_SimResults to Matlab file in the app directory
cMat = [];
x='x2';
for k=3:40
    x=char(x,strcat('x',num2str(k)));
end
x=cellstr(x);
x=x';
ts='T1';
for k=2:41
    ts=char(ts,strcat('T',num2str(k)));
end
ts=cellstr(ts);
ts=ts';
tdesc='bottoms temp (ºC)';
for k=1:39
    tdesc=char(tdesc,strcat('tray',' ',num2str(k), ' temp (ºC)'));
end
tdesc=char(tdesc,'distillate temp (ºC)');
tdesc=cellstr(tdesc);
tdesc=tdesc';
% Create cell array
cMat = {'t' 'F' 'zF' 'TF' 'yD' 'xB' 'MD' 'MB' 'L' 'V' 'D' 'B' ts{:}};
cMat = [cMat; {'time (min)' 'feed volumetric flow (L/h)' 'feed composition' ...
               'feed temperature (ºC)' 'distillate composition' 'bottoms composition' ...
               'condenser holdup (kmol)' 'reboiler holdup (kmol)' 'reflux flow (L/h)' 'boilup flow (L/h)' ...
               'distillate flow (L/h)' 'bottoms flow (L/h)' tdesc{:} }];
cMat = [cMat; num2cell([Results.t  Results.FV Results.zF Results.TF Results.yD Results.xB ...
                        Results.MD Results.MB Results.L Results.V Results.D Results.B ...
                        Results.Temp(:,1:41)])];


% --- Executes on button press in chkAddSecondOP.
function chkAddSecondOP_Callback(hObject, eventdata, handles)
% hObject    handle to chkAddSecondOP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkAddSecondOP

if get(handles.chkAddSecondOP,'value')==1
    set(handles.txtTimeChangeOperatingPoint,'enable','on');
    set(handles.cmbSecondOP,'enable','on');
    cmbSecondOP_Callback(handles.cmbSecondOP, eventdata, handles);
else
    set(handles.txtTimeChangeOperatingPoint,'enable','off');
    set(handles.cmbSecondOP,'enable','off');
    set(handles.txtXBs_2,'string',get(handles.txtXBs_1,'string'));
    set(handles.txtYDs_2,'string',get(handles.txtYDs_1,'string'));
end
SaveParam(hObject,handles,2);



function txtYDs_2_Callback(hObject, eventdata, handles)
% hObject    handle to txtYDs_2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtYDs_2 as text
%        str2double(get(hObject,'String')) returns contents of txtYDs_2 as a double


% --- Executes during object creation, after setting all properties.
function txtYDs_2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtYDs_2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtXBs_2_Callback(hObject, eventdata, handles)
% hObject    handle to txtXBs_2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtXBs_2 as text
%        str2double(get(hObject,'String')) returns contents of txtXBs_2 as a double


% --- Executes during object creation, after setting all properties.
function txtXBs_2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtXBs_2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtXBs_1_Callback(hObject, eventdata, handles)
% hObject    handle to txtXBs_1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtXBs_1 as text
%        str2double(get(hObject,'String')) returns contents of txtXBs_1 as a double


% --- Executes during object creation, after setting all properties.
function txtXBs_1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtXBs_1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function txtYDs_1_Callback(hObject, eventdata, handles)
% hObject    handle to txtYDs_1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtYDs_1 as text
%        str2double(get(hObject,'String')) returns contents of txtYDs_1 as a double


% --- Executes during object creation, after setting all properties.
function txtYDs_1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtYDs_1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function mnuExport_Callback(hObject, eventdata, handles)
% hObject    handle to mnuExport (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
Export(handles,'excel');


% --------------------------------------------------------------------
function mnuExportMat_Callback(hObject, eventdata, handles)
% hObject    handle to mnuExportMat (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
Export(handles,'matlab');


function Export(handles,sType)
bShowMessage = 0;
if isfield(handles, 'NumberOfTests')
    nTests = handles.NumberOfTests;
else
    nTests = 0;
end
nProg = 2 + nTests;
iProg = 0;
hProg = waitbar(0/iProg, 'Exporting simulation results ...');
[pathstr, sName, ext] = fileparts(handles.P1_SimParam.BenchmarkName);
switch sType
    case 'excel'
        sName = strcat(sName,'.xls');
    otherwise
        struct_Mat.Benchmark = sName;
        sName = strcat(sName,'.mat');
end            
if isfield(handles,'P1_SimResults')
    switch sType
        case 'excel'
            sSheet = 'Phase I';
        otherwise
            sSheet = 'Phase_I';
    end            
    sTitle = 'Exporting simulation results (Phase I) ...';
    Results = handles.P1_SimResults;
    iProg = iProg + 1;
    waitbar(iProg/nProg,hProg,sTitle);
    switch sType
        case 'excel'
            ExportToExcel(sName,sSheet,Results);
        otherwise
            struct_Mat.(sSheet) = ExportToMatlab(Results);
    end            
    bShowMessage = 1;
end
if nTests > 0
    for iTestId = 1:nTests
        sTestId = sprintf('%02d',iTestId);
        sField = ['P2_SimResults_' sTestId];
        if isfield(handles, sField) 
            switch sType
                case 'excel'
                    sSheet = ['Phase II (Test ' sTestId ')'];
                otherwise
                    sSheet = ['Phase_II_Test_' sTestId];
            end            
            sTitle = ['Exporting simulation results (Phase II - Test ' sTestId ') ...'];
            sSimResults = ['P2_SimResults_' sTestId];
            sEval = ['Results = handles.' sSimResults ';'];
            eval(sEval);
            iProg = iProg + 1;
            waitbar(iProg/nProg,hProg,sTitle);
            switch sType
                case 'excel'
                    ExportToExcel(sName,sSheet,Results);
                otherwise
                    struct_Mat.(sSheet) = ExportToMatlab(Results);
            end            
            bShowMessage = 1;
        end
    end
end
if bShowMessage==1 && strcmp(sType,'matlab')
    save(sName,'-struct','struct_Mat');
end
waitbar(1/1,hProg,'Process complete');
close(hProg);

if bShowMessage==1
    msgbox('Process complete', 'Export to Excel');
end

% --------------------------------------------------------------------
function mnuPhaseIComputePCA_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIComputePCA (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Compute PCA model with full dataset
PhaseIComputePCA(hObject,handles,0);
% For external data, get NOC data and compute PCA model again
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    PhaseIComputePCA(hObject,handles,1);
end


% --------------------------------------------------------------------
function PhaseIComputePCA(hObject,handles,bGetNOCdata)
%% Generate Z matrix
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    [Z,vnames] = construct_Z(handles.Dataset,0,1);
    handles.P1_SimResults.VariableNames = vnames;
else
    if ~check_errors('handles', handles, 'sType', 'phaseI_data')
        return;
    end
    P1_SimResults = handles.P1_SimResults;
    if isfield(P1_SimResults, 'Zoptimum') 
        Z = P1_SimResults.Zoptimum;
        vnames = P1_SimResults.VariableNames;
    else
        [Z,vnames] = construct_Z(P1_SimResults,0,0);
        handles.P1_SimResults.VariableNames = vnames;
    end
end

if bExternalDS && bGetNOCdata
    % Compute PCA through SVD with full dataset ...
    PCA_res = PCA_SVD(Z,0,2);
    % Get NOC data for external data sources
    % Generate matrix with id observations, T2 and SPE values
    mOCP_full = [(1:PCA_res.N)' PCA_res.Tsquared(:) PCA_res.SPE(:)];
    mOCP_high = mOCP_full;
    %   (1) Remove observations with SPE or T2 greater than 2 times corresponding UCL
    idMaxUCL = [];
    indMaxUCL = (mOCP_high(:,2) >= 2*PCA_res.UCL_T2_05) | (mOCP_high(:,3) >= 2*PCA_res.SPE_UCL_05);
    if any(indMaxUCL)
        % Get obs ids ...
        idMaxUCL = mOCP_high(indMaxUCL,1);
        % Remove obs ...
        mOCP_high = mOCP_high(~indMaxUCL,:);
    end
    %   (2) From remaining observations, remove "n" observations to have 5% maximum of
    %   out-of-control (OOC) points
    nOCP = size(mOCP_high,1);
    % Find obs with T2>UCL(T2) and remove obs with greater T2 in order to have 5% of OOC points
    pOOC = sum(mOCP_high(:,2) >= PCA_res.UCL_T2_05)*100/nOCP;
    idT2 = [];
    if pOOC>5
        % Number of obs to remove to have 5% of OOC points
        nRemove = ceil((pOOC-5)*nOCP/100);
        % Sort by T2 in descendin order ...
        mOCP_high = sortrows(mOCP_high,-2);
        idT2 = mOCP_high(1:nRemove,1);
    end
    % Find obs with SPE>UCL(SPE) and remove obs with greater SPE in order to have 5% of OOC points
    pOOC = sum(mOCP_high(:,3) >= PCA_res.SPE_UCL_05)*100/nOCP;
    idSPE = [];
    if pOOC>5
        % Number of obs to remove to have 5% of OOC points
        nRemove = ceil((pOOC-5)*nOCP/100);
        % Sort by SPE in descendin order ...
        mOCP_high = sortrows(mOCP_high,-3);
        idSPE = mOCP_high(1:nRemove,1);
    end
    % Remove observations and compute PCA again with NOC data
    idRemove = [idMaxUCL;idT2;idSPE];
    if ~isempty(idRemove)
        % Plot removed obs ...
        MSPC_SPE('title','Phase I. PCA results. SPE chart (full dataset)',...
                 'phase',1,...
                 't',(1:PCA_res.N),...
                 'A',PCA_res.A,...
                 'SPE',PCA_res.SPE,...
                 'SPE_UCL_01',PCA_res.SPE_UCL_01,...
                 'SPE_UCL_05',PCA_res.SPE_UCL_05,...
                 'Enew',[],...
                 'EnewSquared',[],...
                 'VariableNames',handles.P1_SimResults.VariableNames, ...
                 'IdRemovedObs', idRemove);
        MSPC_T2('title','Phase I. PCA results. T2 chart (full dataset)',...
                'phase',1,...
                't',(1:PCA_res.N),...
                'T',PCA_res.T,...
                'Tsquared',PCA_res.Tsquared,...
                'UCL_T2_01',PCA_res.UCL_T2_01,...
                'UCL_T2_05',PCA_res.UCL_T2_05,...
                'P',PCA_res.P,...
                'L',PCA_res.L,...
                'A',PCA_res.A,...
                'Xnew',[],...
                'VariableNames',handles.P1_SimResults.VariableNames, ...
                'IdRemovedObs', idRemove);
        % Remove ids with high T2/SPE to get NOC data ...
        indRem = (ismember(mOCP_full(:,1),idRemove));
        Z = Z(~indRem,:);
        % Compute PCA with NOC data ...
        PCA_res = PCA_SVD(Z,1,3);
    end
else
    % Compute PCA through SVD with full dataset ...
    if bExternalDS
        bType = 2;
    else
        bType = 1;
    end
    PCA_res = PCA_SVD(Z,1,bType);
end

%% Store PCA P1_SimResults ...
P1_PCAResults = struct('N',PCA_res.N,...
                       'K',PCA_res.K,...
                       'A',PCA_res.A,...
                       'Zmean',PCA_res.Zmean,...
                       'Zstd',PCA_res.Zstd,...
                       'X',PCA_res.X,...
                       'T',PCA_res.T,...
                       'P',PCA_res.P,...
                       'L',PCA_res.L,...
                       'E',PCA_res.E,...
                       'Tsquared',PCA_res.Tsquared,...
                       'UCL_T2_01',PCA_res.UCL_T2_01,...
                       'UCL_T2_05',PCA_res.UCL_T2_05,...
                       'SPE',PCA_res.SPE,...
                       'SPE_UCL_01',PCA_res.SPE_UCL_01,...
                       'SPE_UCL_05',PCA_res.SPE_UCL_05);
handles.P1_PCAResults = P1_PCAResults;
guidata(hObject, handles);
set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback

%% Scores ...
sTitle = 'Phase I. Score scattered plot';
if bExternalDS
    % Add observation ids as 't'
    handles.P1_SimResults.t = 1:PCA_res.N;
    if bGetNOCdata
        sTitle = [sTitle ' (NOC dataset)'];
    else
        sTitle = [sTitle ' (full dataset)'];
    end
end
MSPC_scores('title',sTitle,...
            'phase',1,...
            't',handles.P1_SimResults.t,...
            'A',handles.P1_PCAResults.A,...
            'N',handles.P1_PCAResults.N,...
            'T',handles.P1_PCAResults.T,...
            'L',handles.P1_PCAResults.L,...
            'P',handles.P1_PCAResults.P,...
            'X',handles.P1_PCAResults.X,...
            'VariableNames',handles.P1_SimResults.VariableNames);

save_results(hObject,handles,'no');


% --------------------------------------------------------------------
function PCA_res = PCA_SVD(Z,bPlotVariance,bType)
%  Param "bType"
%    1 ... data from simulation
%    2 ... external data (full dataset)
%    3 ... external data (NOC dataset)
%% Compute PCA through SVD ...
[N K] = size (Z); % N observations, K variables
Zmean = mean(Z);
Zstd = std(Z);
% Standardized X matrix ...
X = (Z - repmat(Zmean,[N 1])) ./ repmat(Zstd,[N 1]);
% SVD ...
try
    [U,S,V] = svd(X);
catch
    [U,S,V] = svd(X,'econ');
end
%Scores
T = U * S;
%Loadings
P = V;
%Eigenvalues of the covariance matrix of X
L = (diag(S) .* diag(S))/(N-1);

%% Variance explained ...
A = PlotVariance(L,bPlotVariance,bType);

%% Compute PCA for a given number of selected PCs
PCA_res = PCA_A(X,N,T,P,L,A);
PCA_res.X = X;
PCA_res.K = K;
PCA_res.Zmean = Zmean;
PCA_res.Zstd = Zstd;



function PCA_res = PCA_A(X,N,T,P,L,A)
% Computes PCA for a given number of selected PCs

%Computing residuals from scores and loadings matrices:
Xstar = T(:,1:A) * P(:,1:A)';
E = X - Xstar;

% Hotelling's T2
% t2, is Hotelling's T2, a statistical measure of the multivariate distance of each observation from the center of the data set.
% This is an analytical way to find the most extreme points in the data.

% Hotelling T2 computation for each observation:
Tsquared = zeros(1,N);
for i=1:N;
    for a = 1:A;
        Tsquared(i) = Tsquared(i) + T(i,a)^2 / L(a);
    end;
end;
% UCL for Hotelling T2 at significance level alpha (Phase I)
alpha = 0.01;
F = finv(1-alpha,A,N-A-1);
B = (A/(N-A-1))*F/(1+(A/(N-A-1))*F);
UCL_T2_01 = (N-1)^2*B/N;
alpha = 0.05;
F = finv(1-alpha,A,N-A-1);
B = (A/(N-A-1))*F/(1+(A/(N-A-1))*F);
UCL_T2_05 = (N-1)^2*B/N;
% Sum of squared prediction errors
SPE = diag(E()*E()');
% UCL for SPE at significance level alpha (Phase I)
SPEmean = mean(SPE);
SPEvar = var(SPE);
alpha = 0.01;
ChiSquared = chi2inv(1-alpha,2*SPEmean^2/SPEvar);
SPE_UCL_01 = SPEvar*ChiSquared/(2*SPEmean);
alpha = 0.05;
ChiSquared = chi2inv(1-alpha,2*SPEmean^2/SPEvar);
SPE_UCL_05 = SPEvar*ChiSquared/(2*SPEmean);

% Create structure to return values
PCA_res = struct('N',N,...
                 'T',T,...
                 'P',P,...
                 'L',L,...
                 'A',A,...
                 'E',E,...
                 'Tsquared',Tsquared,...
                 'UCL_T2_01',UCL_T2_01,...
                 'UCL_T2_05',UCL_T2_05,...
                 'SPE',SPE,...
                 'SPE_UCL_01',SPE_UCL_01,...
                 'SPE_UCL_05',SPE_UCL_05);
% --------------------------------------------------------------------



function mnuPhaseIPCs_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIPCs (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

if ~check_errors('handles', handles, 'sType', 'computePCA')
    return;
end

P1_PCAResults = handles.P1_PCAResults;

sNewA = inputdlg('Input the new number of selected PCs:','Selected PCs',1,{num2str(P1_PCAResults.A)});
if isempty(sNewA)
    return;
end

P1_PCAResults.A = str2num(cell2mat(sNewA));

%% Compute PCA for a given number of selected PCs
pRes = PCA_A(P1_PCAResults.X,P1_PCAResults.N,P1_PCAResults.T,P1_PCAResults.P,P1_PCAResults.L,P1_PCAResults.A);
                   
%% Update PCA P1_SimResults ...
P1_PCAResults.E = pRes.E;
P1_PCAResults.Tsquared = pRes.Tsquared;
P1_PCAResults.UCL_T2_01 = pRes.UCL_T2_01;
P1_PCAResults.UCL_T2_05 = pRes.UCL_T2_05;
P1_PCAResults.SPE = pRes.SPE;
P1_PCAResults.SPE_UCL_01 = pRes.SPE_UCL_01;
P1_PCAResults.SPE_UCL_05 = pRes.SPE_UCL_05;
handles.P1_PCAResults = P1_PCAResults;
guidata(hObject, handles);
set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback

% --------------------------------------------------------------------


function mnuPhaseIScores_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIScores (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[phase,sType,sTestId] = GetPhase(handles);
bExternalDS = (~isempty(handles.DataSourceName));
if phase==1
    if ~check_errors('handles', handles, 'sType', 'computePCA')
        return;
    end
    sTitle = 'Phase I. Score scattered plot';
    if bExternalDS
        t = 1:handles.P1_PCAResults.N;
    else
        t = handles.P1_SimResults.t;
    end
    N = handles.P1_PCAResults.N;
    T = handles.P1_PCAResults.T;
    L = handles.P1_PCAResults.L;
    P = handles.P1_PCAResults.P;
    X = handles.P1_PCAResults.X;
    VariableNames = handles.P1_SimResults.VariableNames;
else
    if ~check_errors('handles', handles, 'sType', 'exploitPCA', 'sTestId', sTestId)
        return;
    end
    sTitle = 'Phase II. Score scattered plot';
    sPCAResults = ['P2_PCAResults_' sTestId];
    if bExternalDS
        sEval = ['t = 1:handles.' sPCAResults '.Nnew;'];
        eval(sEval);
    else
        sSimResults = ['P2_SimResults_' sTestId];
        sEval = ['t = handles.' sSimResults '.t;'];
        eval(sEval);
    end
    sEval = ['N = handles.' sPCAResults '.Nnew;'];
    eval(sEval);
    sEval = ['T = handles.' sPCAResults '.Tnew;'];
    eval(sEval);
    L = handles.P1_PCAResults.L;
    P = handles.P1_PCAResults.P;
    sEval = ['X = handles.' sPCAResults '.Xnew;'];
    eval(sEval);
    VariableNames = handles.P1_SimResults.VariableNames;    
end
MSPC_scores('title',sTitle,...
                        'phase',phase,...
                        't',t,...
                        'A',handles.P1_PCAResults.A,...
                        'N',N,...
                        'T',T,...
                        'L',L,...
                        'P',P,...
                        'X',X,...
                        'VariableNames',VariableNames);


% --------------------------------------------------------------------
function mnuPhaseIHotellingT2_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIHotellingT2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%% Hotelling's T2 plot
[phase,sType,sTestId] = GetPhase(handles);
bExternalDS = (~isempty(handles.DataSourceName));
if phase==1
    if ~check_errors('handles', handles, 'sType', 'computePCA')
        return;
    end
    sTitle = 'Phase I. PCA results. Hotelling''s T2 chart';
    if bExternalDS
        t = 1:handles.P1_PCAResults.N;
    else
        t = handles.P1_SimResults.t;
    end
    T = handles.P1_PCAResults.T;
    Tsquared = handles.P1_PCAResults.Tsquared;
    P = handles.P1_PCAResults.P;
    L = handles.P1_PCAResults.L;
    Xnew = [];
else
    sTitle = ['Phase II. Test ' sTestId '. PCA results. Hotelling''s T2 chart'];
    sPCAResults = ['P2_PCAResults_' sTestId];
    if bExternalDS
        sEval = ['t = 1:handles.' sPCAResults '.Nnew;'];
        eval(sEval);
    else
        sSimResults = ['P2_SimResults_' sTestId];
        if ~check_errors('handles', handles, 'sType', 'exploitPCA', 'sTestId', sTestId)
            return;
        end
        sEval = ['t = handles.' sSimResults '.t;'];
        eval(sEval);
    end
    sEval = ['T = handles.' sPCAResults '.Tnew;'];
    eval(sEval);
    sEval = ['Tsquared = handles.' sPCAResults '.TsquaredNew;'];
    eval(sEval);
    P = handles.P1_PCAResults.P;
    L = handles.P1_PCAResults.L;
    sEval = ['Xnew = handles.' sPCAResults '.Xnew;'];
    eval(sEval);
end

UCL_T2_01 = handles.P1_PCAResults.UCL_T2_01; %The same for Phase I and Phase II
UCL_T2_05 = handles.P1_PCAResults.UCL_T2_05;

MSPC_T2('title',sTitle,...
        'phase',phase,...
        't',t,...
        'T',T,...
        'Tsquared',Tsquared,...
        'UCL_T2_01',UCL_T2_01,...
        'UCL_T2_05',UCL_T2_05,...
        'P',P,...
        'L',L,...
        'A',handles.P1_PCAResults.A,...
        'Xnew',Xnew,...
        'VariableNames',handles.P1_SimResults.VariableNames);
                 
% --------------------------------------------------------------------




function mnuPhaseISPE_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseISPE (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%% SPE plot
[phase,sType,sTestId] = GetPhase(handles);
bExternalDS = (~isempty(handles.DataSourceName));
if phase==1
    if ~check_errors('handles', handles, 'sType', 'computePCA')
        return;
    end
    sTitle = 'Phase I. PCA results. SPE chart';
    if bExternalDS
        t = 1:handles.P1_PCAResults.N;
    else
        t = handles.P1_SimResults.t;
    end
    SPE = handles.P1_PCAResults.SPE;
    Enew = [];
    EnewSquared = [];
else
    sTitle = ['Phase II. Test ' sTestId '. PCA results. SPE chart'];
    sPCAResults = ['P2_PCAResults_' sTestId];
    if bExternalDS
        sEval = ['t = 1:handles.' sPCAResults '.Nnew;'];
        eval(sEval);
    else
        sSimResults = ['P2_SimResults_' sTestId];
        if ~check_errors('handles', handles, 'sType', 'exploitPCA', 'sTestId', sTestId)
            return;
        end
        sEval = ['t = handles.' sSimResults '.t;'];
        eval(sEval);
    end
    sEval = ['SPE = handles.' sPCAResults '.SPEnew;'];
    eval(sEval);
    sEval = ['Enew = handles.' sPCAResults '.Enew;'];
    eval(sEval);
    sEval = ['EnewSquared = handles.' sPCAResults '.EnewSquared;'];
    eval(sEval);
end
SPE_UCL_01 = handles.P1_PCAResults.SPE_UCL_01; %The same for Phase I and Phase II
SPE_UCL_05 = handles.P1_PCAResults.SPE_UCL_05;

MSPC_SPE('title',sTitle,...
         'phase',phase,...
         't',t,...
         'A',handles.P1_PCAResults.A,...
         'SPE',SPE,...
         'SPE_UCL_01',SPE_UCL_01,...
         'SPE_UCL_05',SPE_UCL_05,...
         'Enew',Enew,...
         'EnewSquared',EnewSquared,...
         'VariableNames',handles.P1_SimResults.VariableNames);


% --------------------------------------------------------------------
function mnuPhaseII_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseII (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function mnuPhaseIIRun_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIRun (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

mnuPhaseIRun_Callback(hObject, eventdata, handles);


% --------------------------------------------------------------------
function mnuPhaseIIPlot_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIPlotResults (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
sTestId = get(handles.txtTestId,'string');
PlotResults(handles,2,sTestId);



function txtBenchmarkName_Callback(hObject, eventdata, handles)
% hObject    handle to txtBenchmarkName (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtBenchmarkName as text
%        str2double(get(hObject,'String')) returns contents of txtBenchmarkName as a double


% --- Executes during object creation, after setting all properties.
function txtBenchmarkName_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtBenchmarkName (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtBenchmarkDesc_Callback(hObject, eventdata, handles)
% hObject    handle to txtBenchmarkDesc (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtBenchmarkDesc as text
%        str2double(get(hObject,'String')) returns contents of txtBenchmarkDesc as a double
SaveParam(hObject,handles,1);


% --- Executes during object creation, after setting all properties.
function txtBenchmarkDesc_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtBenchmarkDesc (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function mnuNew_Callback(hObject, eventdata, handles)
% hObject    handle to mnuNew (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Choose data source: Simulink model or external data
handles.DataSourceName = [];
resp = questdlg('Do you want to use external data?','Data source','Yes','No','No');
if strcmp(resp,'Yes')
    % Open data source
    [dsFileName,dsPathName] = uigetfile({'*.csv','CSV (semicolon-delimited)'}, ...
                                         'Open data source');
    if ~isequal(dsFileName,0)
        dsFile = fullfile(dsPathName, dsFileName);
    else
        return;
    end
    % Load data: in CSV format and the first row contains variable names
    hProg = waitbar(0, 'Importing data ...');
    handles.Dataset = dataset('file',dsFile, ...
                                      'delimiter',';', ...
                                      'ReadVarNames',true, ...
                                      'ReadObsNames',false);
	handles.DataSourceName = dsFile;
    waitbar(1,hProg,'Process complete');
    close(hProg);
end
% Benchmark name
c = clock;
sName = strcat('Sim_',num2str(c(1)),sprintf('%02d',c(2)),sprintf('%02d',c(3)), ...
               sprintf('%02d',c(4)),sprintf('%02d',c(5)),sprintf('%02d',round(c(6))));
sName = inputdlg('Input a name for the new benchmark:','New benchmark',1,{sName});
if isempty(sName)
    exit function;
end
sName = [char(sName) '.cdb'];
handles.BenchmarkName = sName;
handles.BenchmarkDesc = '';
set(handles.txtBenchmarkName,'string',sName);

ClearResults(hObject,handles);

% Load default values ...
handles.P1_SimParam = handles.P1_SimParam_DefaultValues;
Load_P1_SimParam(eventdata,handles,handles.P1_SimParam_DefaultValues);
handles.P1_SimParam.BenchmarkName = sName;
Load_P2_SimParam(eventdata,handles,handles.P2_SimParam_DefaultValues,'01');

UpdateTreeView(hObject, eventdata, handles, 'new');


function handles = ClearResults(hObject,handles)
%Clear handles data
if isfield(handles, 'P1_SimParam') 
    handles = rmfield(handles, 'P1_SimParam');
end
if isfield(handles, 'P1_SimResults') 
    handles = rmfield(handles, 'P1_SimResults');
end
if isfield(handles, 'P1_PCAResults') 
    handles = rmfield(handles, 'P1_PCAResults');
end
if isfield(handles, 'NumberOfTests')
    NumberOfTests = handles.NumberOfTests;
    for idSim=1:NumberOfTests
        sField = ['P2_SimParam_' sprintf('%02d',idSim)];
        if isfield(handles, sField) 
            handles = rmfield(handles, sField);
        end
        sField = ['P2_SimResults_' sprintf('%02d',idSim)];
        if isfield(handles, sField) 
            handles = rmfield(handles, sField);
        end
        sField = ['P2_PCAResults_' sprintf('%02d',idSim)];
        if isfield(handles, sField) 
            handles = rmfield(handles, sField);
        end
    end
    handles = rmfield(handles, 'NumberOfTests');
end
guidata(hObject, handles);
if isfield(handles, 'mTree')
    set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback
end


function RunSimulation(hObject,handles)

global mPath

hProg = waitbar(1/3,'Updating model parameters ...');

if isempty(find_system('Name','colas_PI'))
    load_system('colas_PI');
end

tSample = str2double(get(handles.txtSampleTime,'string'));
hws = get_param('colas_PI', 'modelworkspace');
%Update simulink parameters
assignin(hws, 'Sample_time', tSample);
assignin(hws, 'AddNoise', get(handles.chkNoise,'value'));
phase = GetPhase(handles);
P1_SimParam = handles.P1_SimParam;
%Feed signals ...
if phase==1
    tSim = str2num(get(handles.txtSimTime,'string'));
else
    tSim = str2num(get(handles.txtSimTimePhaseII,'string'));
end
ChangePeriod = str2double(get(handles.txtChangeRatio_Period,'string'));
%Z
initialValue = 0.5;
if get(handles.chkEnableFeedChanges,'value')
    ChangeRatio = str2double(get(handles.txtChangeRatio_z,'string'));
else
    ChangeRatio = 0;
end
nTypeFeedSignal = 2;
signal_z = CreateFeedSignal(tSim,tSample,nTypeFeedSignal,initialValue,ChangeRatio,ChangePeriod);
assignin(hws, 'SignalZ', signal_z);
%T
initialValue = 55;
if get(handles.chkEnableFeedChanges,'value')
    ChangeRatio = str2double(get(handles.txtChangeRatio_T,'string'));
else
    ChangeRatio = 0;
end
signal_T = CreateFeedSignal(tSim,tSample,nTypeFeedSignal,initialValue,ChangeRatio,ChangePeriod);
assignin(hws, 'SignalT', signal_T);
%F
initialValue = 2868.14;
if get(handles.chkEnableFeedChanges,'value')
    ChangeRatio = str2double(get(handles.txtChangeRatio_F,'string'));
else
    ChangeRatio = 0;
end
signal_F = CreateFeedSignal(tSim,tSample,nTypeFeedSignal,initialValue,ChangeRatio,ChangePeriod);
assignin(hws, 'SignalF', signal_F);
if phase==1
    %Disable disturbances for Phase I ...
    assignin(hws, 'ActivateDisturbances_z', 0);
    assignin(hws, 'SignalDisturbZ', [0 0]);
    assignin(hws, 'ActivateDisturbances_T', 0);
    assignin(hws, 'SignalDisturbT', [0 0]);
    assignin(hws, 'ActivateDisturbances_F', 0);
    assignin(hws, 'SignalDisturbF', [0 0]);
    assignin(hws, 'Activate_PI_Failure_xB', 0);
    assignin(hws, 'Activate_PI_Failure_yD', 0);
else
    %Disturbances...
    assignin(hws, 'ActivateDisturbances_z', get(handles.chkActDisturb_z,'value'));
    ChangePeriod = str2double(get(handles.txtChangeRatio_Period,'string'));
    Zo = 0.5;
    timeZ = str2double(get(handles.txtDisturbanceTime_z,'string'));
    typeZ = get(handles.cmbDisturbanceType_z,'value');
    sizeZ = str2double(get(handles.txtDisturbanceSize_z,'string'));
    durationZ = str2double(get(handles.txtDisturbanceDuration_z,'string'));
    pulseDurationZ = str2double(get(handles.txtPulseDuration_z,'string'));
    if get(handles.chkActDisturb_z,'value')
        if get(handles.chkEnableFeedChanges,'value')
            ChangeRatio = str2double(get(handles.txtChangeRatio_z,'string'));
        else
            ChangeRatio = 0;
        end
        signalDisturbZ = CreateDisturbanceSignal(tSample,timeZ,typeZ,Zo,sizeZ,durationZ,pulseDurationZ,signal_z);
        assignin(hws, 'SignalDisturbZ', signalDisturbZ); %signal must be in workspace
    else
        assignin(hws, 'SignalDisturbZ', [0 0]); %signal must be in workspace
    end
    assignin(hws, 'ActivateDisturbances_T', get(handles.chkActDisturb_T,'value'));
    To = 55;
    timeT = str2double(get(handles.txtDisturbanceTime_T,'string'));
    typeT = get(handles.cmbDisturbanceType_T,'value');
    sizeT = str2double(get(handles.txtDisturbanceSize_T,'string'));
    durationT = str2double(get(handles.txtDisturbanceDuration_T,'string'));
    pulseDurationT = str2double(get(handles.txtPulseDuration_T,'string'));
    if get(handles.chkActDisturb_T,'value')
        if get(handles.chkEnableFeedChanges,'value')
            ChangeRatio = str2double(get(handles.txtChangeRatio_T,'string'));
        else
            ChangeRatio = 0;
        end
        signalDisturbT = CreateDisturbanceSignal(tSample,timeT,typeT,To,sizeT,durationT,pulseDurationT,signal_T);
        assignin(hws, 'SignalDisturbT', signalDisturbT); %signal must be in workspace
    else
        assignin(hws, 'SignalDisturbT', [0 0]); %signal must be in workspace
    end
    assignin(hws, 'ActivateDisturbances_F', get(handles.chkActDisturb_F,'value'));
    Fo = 2868.14;
    timeF = str2double(get(handles.txtDisturbanceTime_F,'string'));
    typeF = get(handles.cmbDisturbanceType_F,'value');
    sizeF = str2double(get(handles.txtDisturbanceSize_F,'string'));
    durationF = str2double(get(handles.txtDisturbanceDuration_F,'string'));
    pulseDurationF = str2double(get(handles.txtPulseDuration_F,'string'));
    if get(handles.chkActDisturb_F,'value')
        if get(handles.chkEnableFeedChanges,'value')
            ChangeRatio = str2double(get(handles.txtChangeRatio_F,'string'));
        else
            ChangeRatio = 0;
        end
        signalDisturbF = CreateDisturbanceSignal(tSample,timeF,typeF,Fo,sizeF,durationF,pulseDurationF,signal_F);
        assignin(hws, 'SignalDisturbF', signalDisturbF); %signal must be in workspace
    else
        assignin(hws, 'SignalDisturbF', [0 0]); %signal must be in workspace
    end
    assignin(hws, 'Activate_PI_Failure_xB', get(handles.chkActFailure_xB,'value'));
    assignin(hws, 'Time_PI_Failure_xB', str2double(get(handles.txtTimeFailure_xB,'string')));
    assignin(hws, 'Activate_PI_Failure_yD', get(handles.chkActFailure_yD,'value'));
    assignin(hws, 'Time_PI_Failure_yD', str2double(get(handles.txtTimeFailure_yD,'string')));
end
if phase ==1
    assignin(hws, 'xBs_1', str2double(get(handles.txtXBs_1,'string')));
    assignin(hws, 'yDs_1', str2double(get(handles.txtYDs_1,'string')));
else
    assignin(hws, 'xBs_1', P1_SimParam.xBs_1);
    assignin(hws, 'yDs_1', P1_SimParam.yDs_1);
end
if phase==2 && get(handles.chkAddSecondOP,'value')==1
    assignin(hws, 'TimeChangeOperatingPoint', str2double(get(handles.txtTimeChangeOperatingPoint,'string')));
    assignin(hws, 'xBs_2', str2double(get(handles.txtXBs_2,'string')));
    assignin(hws, 'yDs_2', str2double(get(handles.txtYDs_2,'string')));
else
    % There's no OP change, then xBs_2=xBs_1 and yDs_2=yDs_1 ...
    assignin(hws, 'TimeChangeOperatingPoint', tSim);
    assignin(hws, 'xBs_2', str2double(get(handles.txtXBs_1,'string')));
    assignin(hws, 'yDs_2', str2double(get(handles.txtYDs_1,'string')));    
end
%Update initialize file
if phase ==1
    OP_1 = get(handles.cmbFirstOP,'value');
else
    OP_1 = P1_SimParam.OP_1;
end

switch OP_1
    case 1
        % Operating point 1: xB = 0.01, yD = 0.99
        sSource = 'cola_init_PO1.mat';
    case 2
        % Operating point 1: xB = 0.01, yD = 0.96
        sSource = 'cola_init_PO2.mat';
    case 3
        % Operating point 1: xB = 0.05, yD = 0.99
        sSource = 'cola_init_PO3.mat';
end
sSource = fullfile(mPath,sSource);
copyfile(sSource,'cola_init.mat','f');
load(fullfile(mPath,'cola_init.mat'));
set_param('colas_PI/L0','value',num2str(Uinit(1),16));
set_param('colas_PI/V0','value',num2str(Uinit(2),16));
save_system('colas_PI');

%Run simulation
waitbar(2/3,hProg,'Running simulation ...');

try
    simout=sim('colas_PI',tSim);
catch ME1
    close(hProg);
    errordlg(getReport(ME1),'Simulation error');
    return
end

% Set up the SimResults data structure
SimResults = struct('t',      t,...
                'zF',     zF,...
                'TF',     TF,...
                'qF',     qF,...
                'FV',     FV,...
                'FM',     FM,...
                'V',      V,...
                'VM',     VM,...
                'deltaV', deltaV,...
                'L',      L,...
                'LM',     LM,...
                'deltaL', deltaL,...
                'D',      D,...
                'DM',     DM,...
                'B',      B,...
                'BM',     BM,...
                'xB',     xB,...
                'yD',     yD,...
                'MD',     MD,...
                'MB',     MB,...
                'Comp',   Comp,...
                'Temp',   Temp);

% Store the new Results
if phase==1
    handles.P1_SimResults = SimResults;
    % Store param values
    SaveParam(hObject,handles,1);
else
    sTestId = get(handles.txtTestId,'string');
    sEval = ['handles.P2_SimResults_' sTestId ' = SimResults;'];
	eval(sEval);
    SaveParam(hObject,handles,2);
end
guidata(hObject, handles);
set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback
save_results(hObject,handles,'no');
waitbar(3/3,hProg,'Plotting simulation results ...');

if phase==1
    PlotResults(handles);
else
    sTestId = get(handles.txtTestId,'string');
    PlotResults(handles);
end

close(hProg);


% --------------------------------------------------------------------
function mnuPhaseISim_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseISim (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function mnuPhaseIView_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIView (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

UpdateTreeView(hObject, eventdata, handles,'phase1sim');


% --------------------------------------------------------------------
function mnuPhaseIISim_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIISim (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function mnuPhaseIIView_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIIView (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

UpdateTreeView(hObject, eventdata, handles,'phase2sim');


function ActivateControls(handles,action)

switch action
    case 'openwindow'
        sBenchmarkInfo = 'off';
        sPhase1_Sim = 'off';
        sPhase2_Sim = 'off';
        sSave = 'off';
    case {'new','open','phase1sim'}
        sBenchmarkInfo = 'on';
        sPhase1_Sim = 'on';
        sPhase2_Sim = 'off';
        sSave = 'on';
    case 'phase2sim'
        sBenchmarkInfo = 'on';
        sPhase1_Sim = 'off';
        sPhase2_Sim = 'on';
        sSave = 'on';
end

% Panels visibility
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    set(handles.panBenchmarkInfo,'visible','on');
    set(handles.lblExternalData,'visible','on');
    set(handles.txtExternalData,'visible','on');
    set(handles.panPhase1_Sim,'visible','off');
    set(handles.panPhase2_Sim,'visible','off');
    set(handles.tblData,'Units','pixels');
    if strcmp(sPhase1_Sim,'on')
        set(handles.tblData,'Position',[289,11,460,403]);
        set(handles.lblExtTestDesc,'visible','off');
        set(handles.txtExtTestDesc,'visible','off');
    else
        set(handles.tblData,'Position',[289,11,460,355]);
        set(handles.lblExtTestDesc,'visible','on');
        set(handles.txtExtTestDesc,'visible','on');
    end
    set(handles.tblData,'visible','on');
else
    set(handles.panBenchmarkInfo,'visible',sBenchmarkInfo);
    set(handles.lblExternalData,'visible','off');
    set(handles.txtExternalData,'visible','off');
    set(handles.panPhase1_Sim,'visible',sPhase1_Sim);
    set(handles.panPhase2_Sim,'visible',sPhase2_Sim);
    set(handles.tblData,'visible','off');
end

% Menus ...
%  File
%    New benchmark	mnuNew
%    Open benchmark	mnuOpen
%    Save results	mnuSave
%    Save as ...    mnuSaveAs
%    Export to Excel	  mnuExport
%    Export to .mat File  mnuExportMat
%  Phase I
%    Simulation
%       View parameters	mnuPhaseIView
%       Run simulation	mnuPhaseIRun
%       Plot results	mnuPhaseIPlotResults
%    PCA
%       Auto model selection  mnuPhaseIAutoModel
%       Compute PCA           mnuPhaseIComputePCA
%       Selected PCs ...      mnuPhaseIPCs
%       Variance explained    mnuPhaseIVariance
%       Scores                mnuPhaseIScores
%       Hotelling's T2        mnuPhaseIHotellingT2
%       SPE                   mnuPhaseISPE
%  Phase II
%    Simulation
%       View parameters mnuPhaseIIView
%       Run simulation  mnuPhaseIRun
%       Plot results    mnuPhaseIPlotResults

set(handles.mnuSave,'enable',sSave);
set(handles.mnuSaveAs,'enable',sSave);
if bExternalDS
    set(handles.mnuExport,'enable','off');
    set(handles.mnuExportMat,'enable','off');
else
    set(handles.mnuExport,'enable',sSave);
    set(handles.mnuExportMat,'enable',sSave);
end
% Phase I
if bExternalDS
    set(handles.mnuPhaseIRun,'enable','off');
    set(handles.mnuPhaseIPlotResults,'enable','off');
    set(handles.mnuPhaseIAutoModel,'enable','off');
else
    set(handles.mnuPhaseIRun,'enable',sPhase1_Sim);
    set(handles.mnuPhaseIPlotResults,'enable',sPhase1_Sim);
    set(handles.mnuPhaseIAutoModel,'enable',sPhase1_Sim);
end
set(handles.mnuPhaseIComputePCA,'enable',sPhase1_Sim);
set(handles.mnuPhaseIPCs,'enable',sPhase1_Sim);
set(handles.mnuPhaseIVariance,'enable',sPhase1_Sim);
set(handles.mnuPhaseIScores,'enable',sPhase1_Sim);
set(handles.mnuPhaseIHotellingT2,'enable',sPhase1_Sim);
set(handles.mnuPhaseISPE,'enable',sPhase1_Sim);
% Phase II
set(handles.mnuPhaseIINewTest,'enable',sBenchmarkInfo);
if bExternalDS
    set(handles.mnuPhaseIIRun,'enable','off');
    set(handles.mnuPhaseIIPlotResults,'enable','off');
else
    set(handles.mnuPhaseIIRun,'enable',sPhase2_Sim);
    set(handles.mnuPhaseIIPlotResults,'enable',sPhase2_Sim);
end
set(handles.mnuPhaseIIExploitation,'enable',sPhase2_Sim);
set(handles.mnuPhaseIIScores,'enable',sPhase2_Sim);
set(handles.mnuPhaseIIHotellingT2,'enable',sPhase2_Sim);
set(handles.mnuPhaseIISPE,'enable',sPhase2_Sim);

% Toolbar ...
set(handles.tbNew,'enable',get(handles.mnuNew,'enable'));
set(handles.tbOpen,'enable',get(handles.mnuOpen,'enable'));
set(handles.tbSave,'enable',get(handles.mnuSave,'enable'));
set(handles.tbExportToExcel,'enable',get(handles.mnuExport,'enable'));
if strcmp(get(handles.mnuPhaseIRun,'enable'),'on') || strcmp(get(handles.mnuPhaseIIRun,'enable'),'on')
    set(handles.tbRun,'enable','on');
else
    set(handles.tbRun,'enable','off');
end
if strcmp(get(handles.mnuPhaseIPlotResults,'enable'),'on') || strcmp(get(handles.mnuPhaseIIPlotResults,'enable'),'on')
    set(handles.tbPlot,'enable','on');
else
    set(handles.tbPlot,'enable','off');
end
if strcmp(get(handles.mnuPhaseIComputePCA,'enable'),'on') 
    set(handles.tbComputePCA,'enable','on');
else
    set(handles.tbComputePCA,'enable','off');
end
if strcmp(get(handles.mnuPhaseIVariance,'enable'),'on') 
    set(handles.tbVariance,'enable','on');
else
    set(handles.tbVariance,'enable','off');
end
if strcmp(get(handles.mnuPhaseIScores,'enable'),'on') || strcmp(get(handles.mnuPhaseIIScores,'enable'),'on')
    set(handles.tbScores,'enable','on');
else
    set(handles.tbScores,'enable','off');
end
if strcmp(get(handles.mnuPhaseIINewTest,'enable'),'on')
    set(handles.tbNewTest,'enable','on');
else
    set(handles.tbNewTest,'enable','off');
end
if strcmp(get(handles.mnuPhaseIIExploitation,'enable'),'on')
    set(handles.tbExploit,'enable','on');
else
    set(handles.tbExploit,'enable','off');
end
if strcmp(get(handles.mnuPhaseIHotellingT2,'enable'),'on') || strcmp(get(handles.mnuPhaseIIHotellingT2,'enable'),'on')
    set(handles.tbT2,'enable','on');
else
    set(handles.tbT2,'enable','off');
end
if strcmp(get(handles.mnuPhaseISPE,'enable'),'on') || strcmp(get(handles.mnuPhaseIISPE,'enable'),'on')
    set(handles.tbSPE,'enable','on');
else
    set(handles.tbSPE,'enable','off');
end



% --- Executes on selection change in cmbFirstOP.
function cmbFirstOP_Callback(hObject, eventdata, handles)
% hObject    handle to cmbFirstOP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns cmbFirstOP contents as cell array
%        contents{get(hObject,'Value')} returns selected item from cmbFirstOP
switch get(hObject,'value')
    case 1
        sXB = '0.01';
        sYD = '0.99';
    case 2
        sXB = '0.01';
        sYD = '0.96';
    case 3
        sXB = '0.05';
        sYD = '0.99';
end

set(handles.txtXBs_1,'string',sXB);
set(handles.txtYDs_1,'string',sYD);
SaveParam(hObject,handles,1);



% --- Executes during object creation, after setting all properties.
function cmbFirstOP_CreateFcn(hObject, eventdata, handles)
% hObject    handle to cmbFirstOP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in cmbSecondOP.
function cmbSecondOP_Callback(hObject, eventdata, handles)
% hObject    handle to cmbSecondOP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns cmbSecondOP contents as cell array
%        contents{get(hObject,'Value')} returns selected item from cmbSecondOP
switch get(hObject,'value')
    case 1
        sXB = '0.01';
        sYD = '0.99';
    case 2
        sXB = '0.01';
        sYD = '0.96';
    case 3
        sXB = '0.05';
        sYD = '0.99';
end

set(handles.txtXBs_2,'string',sXB);
set(handles.txtYDs_2,'string',sYD);
SaveParam(hObject,handles,2);


        
% --- Executes during object creation, after setting all properties.
function cmbSecondOP_CreateFcn(hObject, eventdata, handles)
% hObject    handle to cmbSecondOP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtTimeChangeOperatingPoint_Callback(hObject, eventdata, handles)
% hObject    handle to txtTimeChangeOperatingPoint (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtTimeChangeOperatingPoint as text
%        str2double(get(hObject,'String')) returns contents of txtTimeChangeOperatingPoint as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtTimeChangeOperatingPoint_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtTimeChangeOperatingPoint (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in chkActDisturb_z.
function chkActDisturb_z_Callback(hObject, eventdata, handles)
% hObject    handle to chkActDisturb_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkActDisturb_z
if get(handles.chkActDisturb_z,'value')==1
    sActive = 'on';
else
    sActive = 'off';
end
set(handles.txtDisturbanceTime_z,'enable',sActive);
set(handles.cmbDisturbanceType_z,'enable',sActive);
set(handles.txtDisturbanceSize_z,'enable',sActive);
set(handles.txtDisturbanceDuration_z,'enable',sActive);
cmbDisturbanceType_z_Callback(hObject, eventdata, handles);

SaveParam(hObject,handles,2);



function txtDisturbanceTime_T_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceTime_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceTime_T as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceTime_T as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceTime_T_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceTime_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in cmbDisturbanceType_T.
function cmbDisturbanceType_T_Callback(hObject, eventdata, handles)
% hObject    handle to cmbDisturbanceType_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
SaveParam(hObject,handles,2);


% Hints: contents = cellstr(get(hObject,'String')) returns cmbDisturbanceType_T contents as cell array
%        contents{get(hObject,'Value')} returns selected item from cmbDisturbanceType_T
if get(handles.chkActDisturb_T,'value')==1
    switch get(handles.cmbDisturbanceType_T,'value')
        case {1,2} %spike, ramp
            sActive = 'off';
        case 3 %pulse
            sActive = 'on';
    end
else
    sActive = 'off';
end
set(handles.txtPulseDuration_T,'enable',sActive);



% --- Executes during object creation, after setting all properties.
function cmbDisturbanceType_T_CreateFcn(hObject, eventdata, handles)
% hObject    handle to cmbDisturbanceType_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in chkActDisturb_T.
function chkActDisturb_T_Callback(hObject, eventdata, handles)
% hObject    handle to chkActDisturb_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkActDisturb_T
if get(handles.chkActDisturb_T,'value')==1
    sActive = 'on';
else
    sActive = 'off';
end
set(handles.txtDisturbanceTime_T,'enable',sActive);
set(handles.cmbDisturbanceType_T,'enable',sActive);
set(handles.txtDisturbanceSize_T,'enable',sActive);
set(handles.txtDisturbanceDuration_T,'enable',sActive);
cmbDisturbanceType_T_Callback(hObject, eventdata, handles);

SaveParam(hObject,handles,2);



function txtDisturbanceTime_F_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceTime_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceTime_F as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceTime_F as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceTime_F_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceTime_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in cmbDisturbanceType_F.
function cmbDisturbanceType_F_Callback(hObject, eventdata, handles)
% hObject    handle to cmbDisturbanceType_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns cmbDisturbanceType_F contents as cell array
%        contents{get(hObject,'Value')} returns selected item from cmbDisturbanceType_F
if get(handles.chkActDisturb_F,'value')==1
    switch get(handles.cmbDisturbanceType_F,'value')
        case {1,2} %spike, ramp
            sActive = 'off';
        case 3 %pulse
            sActive = 'on';
    end
else
	sActive = 'off';
end
set(handles.txtPulseDuration_F,'enable',sActive);
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function cmbDisturbanceType_F_CreateFcn(hObject, eventdata, handles)
% hObject    handle to cmbDisturbanceType_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in chkActDisturb_F.
function chkActDisturb_F_Callback(hObject, eventdata, handles)
% hObject    handle to chkActDisturb_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkActDisturb_F
if get(handles.chkActDisturb_F,'value')==1
    sActive = 'on';
else
    sActive = 'off';
end
set(handles.txtDisturbanceTime_F,'enable',sActive);
set(handles.cmbDisturbanceType_F,'enable',sActive);
set(handles.txtDisturbanceSize_F,'enable',sActive);
set(handles.txtDisturbanceDuration_F,'enable',sActive);
cmbDisturbanceType_F_Callback(hObject, eventdata, handles);

SaveParam(hObject,handles,2);



function txtTimeFailure_xB_Callback(hObject, eventdata, handles)
% hObject    handle to txtTimeFailure_xB (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtTimeFailure_xB as text
%        str2double(get(hObject,'String')) returns contents of txtTimeFailure_xB as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtTimeFailure_xB_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtTimeFailure_xB (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in chkActFailure_xB.
function chkActFailure_xB_Callback(hObject, eventdata, handles)
% hObject    handle to chkActFailure_xB (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkActFailure_xB
if get(handles.chkActFailure_xB,'value')==1
    set(handles.txtTimeFailure_xB,'enable','on');
else
    set(handles.txtTimeFailure_xB,'enable','off');
end
SaveParam(hObject,handles,2);



function txtTimeFailure_yD_Callback(hObject, eventdata, handles)
% hObject    handle to txtTimeFailure_yD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtTimeFailure_yD as text
%        str2double(get(hObject,'String')) returns contents of txtTimeFailure_yD as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtTimeFailure_yD_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtTimeFailure_yD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in chkActFailure_yD.
function chkActFailure_yD_Callback(hObject, eventdata, handles)
% hObject    handle to chkActFailure_yD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkActFailure_yD
if get(handles.chkActFailure_yD,'value')==1
    set(handles.txtTimeFailure_yD,'enable','on');
else
    set(handles.txtTimeFailure_yD,'enable','off');
end
SaveParam(hObject,handles,2);



% --------------------------------------------------------------------
function mnuPhaseIIPCA_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIIPCA (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function mnuPhaseIIExploitation_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIIExploitation (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%% Phase II. Model exploitation
%% Znew construction ...
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    sTestId = get(handles.txtTestId,'string');
    sEval = ['P2_SimParam = handles.P2_SimParam_' sTestId ';'];
    eval(sEval);
    [Znew,vnames] = construct_Z(P2_SimParam.Dataset,0,1);
    % Check names
    if ~isequal(handles.P1_SimResults.VariableNames,vnames)
        msgbox('Model data and validation data field names doesn´t match. Please, check data.','Model exploitation','warn');
        return;
    end
else
    sTestId = get(handles.txtTestId,'string');
    if ~check_errors('handles', handles, 'sType', 'phaseII_data', 'sTestId', sTestId)
        return;
    end
    sEval = ['P2_SimResults = handles.P2_SimResults_' sTestId ';'];
    eval(sEval);
    Znew = construct_Z(P2_SimResults,1,0);
end

%% Exploit model ...
% Scale new data
[Nnew Knew] = size (Znew); % Knew must be equal to K, i.e., the number of variables is the same
% Phase I model parameters needed for calculations ...
P1_PCAResults = handles.P1_PCAResults;
A = P1_PCAResults.A;
Zmean = P1_PCAResults.Zmean;
Zstd = P1_PCAResults.Zstd;
P = P1_PCAResults.P;
% Standardized X (phase II)
Xnew = (Znew - repmat(Zmean,[Nnew 1])) ./ repmat(Zstd,[Nnew 1]);
% Scores for the new observations
Tnew = Xnew * P;
% Model prediction for new observations
Xstarnew = Tnew(:,1:A) * P(:,1:A)';
% Prediction error for new observations
Enew = Xnew - Xstarnew;

%% Phase II. Hotelling's T2
L = handles.P1_PCAResults.L;
TsquaredNew = zeros(1,Nnew);
for i=1:Nnew;
    for a = 1:A;
        TsquaredNew(i) = TsquaredNew(i) + Tnew(i,a)^2 / L(a);
    end;
end;

%% Phase II. SPE
EnewSquared = Enew() .* Enew(); % individual variable contribution to SPE for each observation
SPEnew = sum(EnewSquared,2);

% Save results ...
P2_PCAResults = struct('Nnew',Nnew,...
                       'Knew',Knew,...
                       'Xnew',Xnew,...
                       'Tnew',Tnew,...
                       'Enew',Enew,...
                       'EnewSquared',EnewSquared,...
                       'TsquaredNew',TsquaredNew,...
                       'SPEnew',SPEnew);
sPCAResults = ['P2_PCAResults_' get(handles.txtTestId,'string')];
sEval = ['handles.' sPCAResults ' = P2_PCAResults;'];
eval(sEval);
guidata(hObject, handles);
set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback

%Open T2 and SPE control charts...
mnuPhaseIHotellingT2_Callback(hObject, eventdata, handles);
mnuPhaseISPE_Callback(hObject, eventdata, handles);

save_results(hObject,handles,'no');


% --------------------------------------------------------------------
function mnuPhaseIIHotellingT2_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIIHotellingT2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

mnuPhaseIHotellingT2_Callback(hObject, eventdata, handles);


% --------------------------------------------------------------------
function mnuPhaseIISPE_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIISPE (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

mnuPhaseISPE_Callback(hObject, eventdata, handles);



function [x,vnames] = construct_Z(SimResults,new,bExternal)
if bExternal
    % In this case "SimResults" contains the external dataset
    x = double(SimResults);
    vnames = SimResults.Properties.VarNames();
else
    if new==0
        s = 'Z = [';
    else
        s = 'Znew = [';
    end
    sr = 'SimResults';
    s = [s  sr '.FV, ' sr '.zF, ' sr '.TF, ' sr '.yD, ' sr '.xB, ' sr '.MD, ' sr '.MB, ' sr '.L, ' sr '.V, ' sr '.D, ' sr '.B'];
    vnames = 'vnames = {''F'';''zF'';''TF'';''yD'';;''xB'';''MD'';''MB'';''L'';''V'';''D'';''B''';
    for i=1:41;
        s = [s ', ' sr '.Temp(:,' int2str(i) ')'];
        vnames = [vnames ';''T' int2str(i) ''''];
    end;
    s = [s '];'];
    eval(s);
    vnames = [vnames '};'];
    eval(vnames);
    if new==0
        x = Z;
    else
        x = Znew;    
    end
end


% --- Executes when MSPC_main is resized.
function MSPC_main_ResizeFcn(hObject, eventdata, handles)
% hObject    handle to MSPC_main (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)



function UpdateTreeView(hObject, eventdata, handles, action, idTest)

switch action
    case 'openwindow'
        % No nodes
        
    case 'new'
        % Load default values
        if strcmp(action,'new')
            bExternalDS = (~isempty(handles.DataSourceName));
            if bExternalDS
                handles.NumberOfTests = 0;
            else
                handles.NumberOfTests = 1;
            end
            guidata(hObject, handles);
        end        
    case 'open'
        hProg = waitbar(0/1,'Importing project ...');
        % Read mat file structure ...
        load(handles.FileName, '-mat');
        handles.NumberOfTests = NumberOfTests;
        if exist('DataSourceName','var')
            handles.DataSourceName = DataSourceName;
        end
        if exist('Dataset','var')
            handles.Dataset = Dataset;
        end
        if exist('Dataset','var')
            handles.Dataset = Dataset;
        end
        % Simulation parameters (phase I)
        if exist('P1_SimParam','var')
            handles.P1_SimParam = P1_SimParam;
        else
            handles.P1_SimParam = handles.P1_SimParam_DefaultValues;
            Load_P1_SimParam(eventdata,handles,handles.P1_SimParam_DefaultValues);
        end
        % Simulation results (phase I)
        if exist('P1_SimResults','var')
            handles.P1_SimResults = P1_SimResults;
        end
        % PCA results (phase I)
        % Data is loaded in node click callback
        if exist('P1_PCAResults','var')
            handles.P1_PCAResults = P1_PCAResults;
        end
        % Simulation parameters (phase II)
        for idSim=1:NumberOfTests
            % Simulation param (phase II)
            sTestId = sprintf('%02d',idSim);
            sSimParam = ['P2_SimParam_' sTestId];
            if exist(sSimParam,'var')
                sEval = ['handles.' sSimParam ' = ' sSimParam ';'];
                eval(sEval);
                % Simulation results (phase II)
                sSimResults = ['P2_SimResults_' sTestId];
                if exist(sSimResults,'var')
                    sEval = ['handles.' sSimResults ' = ' sSimResults ';'];
                    eval(sEval);
                end
                % PCA results (phase II)
                sPCAResults = ['P2_PCAResults_' sTestId];
                if exist(sPCAResults,'var')
                    sEval = ['handles.' sPCAResults ' = ' sPCAResults ';'];
                    eval(sEval);
                end
            else
                Load_P2_SimParam(eventdata,handles,handles.P2_SimParam_DefaultValues,sTestId);
            end
        end
        guidata(hObject, handles);
        waitbar(1/1,hProg,'Importing simulation results ...');
        close(hProg);
        
    case 'phase1sim'
        % Data is loaded in node click callback
        
    case 'phase2sim'
        % Data is loaded in node click callback
        
end

% Creates the tree view object
if strcmp(action,'new') ||  strcmp(action,'open')
    CreateTree(hObject,handles,action)
end

ActivateControls(handles,action);


% --- Executes when a tree node is selected
function NodeSelectedCallback(hObject, eventdata, handles)
[phase,sType,sTestId] = GetPhase(handles);
if phase>0
    if phase==1
        % sType:
        %     'Sim' -->  Phase I. Simulation parameters
        %     'PCA' -->  Phase I. PCA results
        bExternalDS = (~isempty(handles.DataSourceName));
        if bExternalDS
            cData = double(handles.Dataset);
            set(handles.tblData,'ColumnName', handles.Dataset.Properties.VarNames, ...
                                'data',cData);
        end
        if isfield(handles,'P1_SimParam');
            P1_SimParam = handles.P1_SimParam;
            Load_P1_SimParam(eventdata,handles,P1_SimParam);
        end
        ActivateControls(handles,'phase1sim');
        if strcmp(sType,'PCA')
            mnuPhaseIComputePCA_Callback(handles.MSPC_main, eventdata, handles);
        end
    elseif (phase==2) && ~isempty(sTestId)
        % sType:
        %     'Sim' -->  Phase II. Simulation parameters
        %     'PCA' -->  Phase II. PCA results
        sPhase2 = ['P2_SimParam_' sTestId];
        bExternalDS = (~isempty(handles.DataSourceName));
        if isfield(handles,sPhase2);
            sEval = ['P2_SimParam = handles.' sPhase2 ';'];
            eval(sEval);
            P2_SimParam.TestId = sTestId;
            if bExternalDS
                cData = double(P2_SimParam.Dataset);
                set(handles.tblData,'ColumnName', P2_SimParam.Dataset.Properties.VarNames, ...
                                    'data',cData);
                set(handles.txtTestId,'string',sTestId);
                set(handles.txtExtTestDesc,'String', P2_SimParam.TestDescription);
            else
                Load_P2_SimParam(eventdata,handles,P2_SimParam,sTestId);
            end
        else
            Load_P2_SimParam(eventdata,handles,handles.P2_SimParam_DefaultValues,sTestId);
            set(handles.txtTestId,'string',sTestId);
        end
        ActivateControls(handles,'phase2sim');
        if strcmp(sType,'PCA')
            mnuPhaseIIExploitation_Callback(handles.MSPC_main, eventdata, handles);
        end
    end
end

function Load_P1_SimParam(eventdata,handles,P1_SimParam)
% Simulation parameters (phase I)
if isfield(P1_SimParam,'BenchmarkName') 
    set(handles.txtBenchmarkName,'string',P1_SimParam.BenchmarkName);
end
set(handles.txtBenchmarkDesc,'string',P1_SimParam.BenchmarkDesc);
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    set(handles.txtExternalData,'string',handles.DataSourceName);
    
else
    set(handles.txtSimTime,'string',P1_SimParam.SimTime);
    set(handles.txtSampleTime,'string',P1_SimParam.SampleTime);
    set(handles.chkNoise,'value',P1_SimParam.AddNoise)
    set(handles.cmbFirstOP,'value',P1_SimParam.OP_1);
    set(handles.txtXBs_1,'string',P1_SimParam.xBs_1);
    set(handles.txtYDs_1,'string',P1_SimParam.yDs_1);
    set(handles.chkEnableFeedChanges,'value',P1_SimParam.EnableFeedChanges);
    chkEnableFeedChanges_Callback(handles.chkEnableFeedChanges, eventdata, handles)
    set(handles.txtChangeRatio_Period,'string',P1_SimParam.ChangeRatio_Period);
    set(handles.txtChangeRatio_F,'string',P1_SimParam.ChangeRatio_FV*100);
    set(handles.txtChangeRatio_T,'string',P1_SimParam.ChangeRatio_TF*100);
    set(handles.txtChangeRatio_z,'string',P1_SimParam.ChangeRatio_zF*100);
end

function Load_P2_SimParam(eventdata,handles,P2_SimParam,sTestId)
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    set(handles.txtBenchmarkName,'string',handles.BenchmarkName);
    set(handles.txtBenchmarkDesc,'string',handles.BenchmarkDesc);
    set(handles.txtExternalData,'string',handles.DataSourceName);
    set(handles.txtExtTestDesc,'string',P2_SimParam.TestDescription);
else
    set(handles.txtTestId,'string',sTestId);
    set(handles.txtTestDescription,'string',P2_SimParam.TestDescription);
    set(handles.txtSimTimePhaseII,'string',P2_SimParam.SimTime);
    set(handles.chkActDisturb_z,'value',P2_SimParam.ActivateDisturbances_z);
    set(handles.txtDisturbanceTime_z,'string',P2_SimParam.DisturbanceTime_z);
    set(handles.cmbDisturbanceType_z,'value',P2_SimParam.DisturbanceType_z);
    set(handles.txtDisturbanceSize_z,'string',P2_SimParam.DisturbanceSize_z);
    set(handles.txtDisturbanceDuration_z,'string',P2_SimParam.DisturbanceDuration_z);
    set(handles.txtPulseDuration_z,'string',P2_SimParam.PulseDuration_z);
    chkActDisturb_z_Callback(handles.chkActDisturb_z, eventdata, handles)
    set(handles.chkActDisturb_T,'value',P2_SimParam.ActivateDisturbances_T);
    set(handles.txtDisturbanceTime_T,'string',P2_SimParam.DisturbanceTime_T);
    set(handles.cmbDisturbanceType_T,'value',P2_SimParam.DisturbanceType_T);
    set(handles.txtDisturbanceSize_T,'string',P2_SimParam.DisturbanceSize_T);
    set(handles.txtDisturbanceDuration_T,'string',P2_SimParam.DisturbanceDuration_T);
    set(handles.txtPulseDuration_T,'string',P2_SimParam.PulseDuration_T);
    chkActDisturb_T_Callback(handles.chkActDisturb_T, eventdata, handles)
    set(handles.chkActDisturb_F,'value',P2_SimParam.ActivateDisturbances_F);
    set(handles.txtDisturbanceTime_F,'string',P2_SimParam.DisturbanceTime_F);
    set(handles.cmbDisturbanceType_F,'value',P2_SimParam.DisturbanceType_F);
    set(handles.txtDisturbanceSize_F,'string',P2_SimParam.DisturbanceSize_F);
    set(handles.txtDisturbanceDuration_F,'string',P2_SimParam.DisturbanceDuration_F);
    set(handles.txtPulseDuration_F,'string',P2_SimParam.PulseDuration_F);
    chkActDisturb_F_Callback(handles.chkActDisturb_F, eventdata, handles)
    set(handles.chkActFailure_xB,'value',P2_SimParam.Activate_PI_Failure_xB);
    set(handles.txtTimeFailure_xB,'string',P2_SimParam.Time_PI_Failure_xB);
    chkActFailure_xB_Callback(handles.chkActFailure_xB, eventdata, handles)    
    set(handles.chkActFailure_yD,'value',P2_SimParam.Activate_PI_Failure_yD);
    set(handles.txtTimeFailure_yD,'string',P2_SimParam.Time_PI_Failure_yD);
    chkActFailure_yD_Callback(handles.chkActFailure_yD, eventdata, handles)    
    set(handles.chkAddSecondOP,'value',P2_SimParam.AddSecondOP);
    set(handles.txtTimeChangeOperatingPoint,'string',P2_SimParam.TimeChangeOperatingPoint);
    set(handles.cmbSecondOP,'value',P2_SimParam.OP_2);
    set(handles.txtXBs_2,'string',P2_SimParam.xBs_2);
    set(handles.txtYDs_2,'string',P2_SimParam.yDs_2);
    chkAddSecondOP_Callback(handles.chkAddSecondOP, eventdata, handles)
end


function cNewNode = CreateNodeTest(handles,cNode_Phase2,idTest)
import javax.swing.*
import javax.swing.tree.*;
%Get node description
sTest = sprintf('%02d',idTest);
sSimParam = ['P2_SimParam_' sTest];
if isfield(handles,sSimParam)
    sEval = ['sDesc = [''  ('' handles.' sSimParam '.TestDescription '')''];'];
    eval(sEval);
else
    sDesc = '';
end
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    sNodeName = 'Validation data ';
else
    sNodeName = 'Test ';
end
handles.cNode_Phase2_Test = uitreenode('v0',['P2' sTest], [sNodeName sTest sDesc], [], 0);
cNode_Phase2.add(handles.cNode_Phase2_Test);
if bExternalDS
    sNodeName = 'External DS';
else
    sNodeName = 'Simulation';
end
cNewNode = uitreenode('v0',['P2Sim' sTest],sNodeName, [], 1);
handles.cNode_Phase2_Test.add(cNewNode);
handles.cNode_Phase2_Test.add(uitreenode('v0',['P2PCA' sTest],'PCA Results', [], 1));



function txtTestId_Callback(hObject, eventdata, handles)
% hObject    handle to txtTestId (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtTestId as text
%        str2double(get(hObject,'String')) returns contents of txtTestId as a double


% --- Executes during object creation, after setting all properties.
function txtTestId_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtTestId (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtTestDescription_Callback(hObject, eventdata, handles)
% hObject    handle to txtTestDescription (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtTestDescription as text
%        str2double(get(hObject,'String')) returns contents of txtTestDescription as a double
SaveParam(hObject,handles,2);


% --- Executes during object creation, after setting all properties.
function txtTestDescription_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtTestDescription (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function mnuPhaseIINewTest_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIINewTest (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

nTest = handles.NumberOfTests;
newTestId = nTest+1;
handles.NumberOfTests = newTestId;
guidata(hObject, handles);
CreateTree(hObject,handles,'newTest')



function CreateTree(hObject,handles,action)
import javax.swing.*
import javax.swing.tree.*;

try
    if ~isempty(handles.mTree)
        delete(handles.mTree);
    end
catch exception
    
end
handles.rootNode = uitreenode('v0', 'root', 'Benchmark', [], 0);
handles.treeModel = DefaultTreeModel(handles.rootNode);
[handles.mTree, handles.TreeCon] = uitree('v0','Root',handles.rootNode);
handles.mTree.setModel( handles.treeModel );
set(handles.TreeCon,'Units', 'normalized','Position',[0 0 0.34 1]);
set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles});
handles.cNode_Phase1 = uitreenode('v0','Phase 1','Phase 1', [], 0);
%cNode.setIcon(javaImage_unchecked);
handles.rootNode.add(handles.cNode_Phase1);
bExternalDS = (~isempty(handles.DataSourceName));
if bExternalDS
    sNodeName = 'External DS';
else
    sNodeName = 'Simulation';
end
cNodeP1Sim = uitreenode('v0','P1Sim',sNodeName, [], 1);
handles.cNode_Phase1.add(cNodeP1Sim);
handles.cNode_Phase1.add(uitreenode('v0','P1PCA', 'PCA Results', [], 1));
% Phase 2 node ...
handles.cNode_Phase2 = uitreenode('v0','P2', 'Phase 2', [], 0);
handles.rootNode.add(handles.cNode_Phase2);
NumberOfTests = handles.NumberOfTests;
if bExternalDS
    % Create nodes ...
    if strcmp(action,'newTest')
        % Ask for data ...
        [dsFileName,dsPathName] = uigetfile({'*.csv','CSV (semicolon-delimited)'}, ...
                                             'Validation data');
        if ~isequal(dsFileName,0)
            dsFile = fullfile(dsPathName, dsFileName);
        else
            return;
        end
        % Load data: in CSV format and the first row contains variable names
        newTest.Dataset = dataset('file',dsFile, ...
                                  'delimiter',';', ...
                                  'ReadVarNames',true, ...
                                  'ReadObsNames',false);
        newTest.DataSourceName = dsFile;
        sNewDesc = inputdlg('Input a description for the dataset:','Test descripction',1,{dsFileName});
        if isempty(sNewDesc)
            return;
        end
        newTest.TestDescription = sNewDesc{:};
        sEval = ['handles.P2_SimParam_' sprintf('%02d',NumberOfTests) ' = newTest;'];
        eval(sEval);
    end
    guidata(hObject, handles);
    set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles});
    for idSim=1:NumberOfTests
        cNewNode = CreateNodeTest(handles,handles.cNode_Phase2,idSim);
    end
else
    CreateNodeTest(handles,handles.cNode_Phase2,1);
    if strcmp(action,'open') || strcmp(action,'newTest')
        if NumberOfTests > 1
            % Create nodes ...
            for idSim=2:NumberOfTests
                cNewNode = CreateNodeTest(handles,handles.cNode_Phase2,idSim);
            end
        end
    end
end
switch action
    case {'new','open'}
        % New/open benchmark: default node Phase 1 - Simulation
        handles.mTree.setSelectedNode(cNodeP1Sim);
    case 'newTest'
        % New test in Phase 2: default node is new added test
        handles.mTree.setSelectedNode(cNewNode);
end

guidata(hObject, handles);


function CreateDefaultValues(hObject, handles)
% Set up the P1_SimParam data structure
handles.P1_SimParam_DefaultValues = struct('BenchmarkDesc',            '',...
                                           'SimTime',                  100,...
                                           'SampleTime',               0.5,...
                                           'AddNoise',                 1,...
                                           'OP_1',                     1,...
                                           'xBs_1',                    0.01,...
                                           'yDs_1',                    0.99,...
                                           'EnableFeedChanges',        1,...
                                           'ChangeRatio_Period',       10,...
                                           'ChangeRatio_FV',           0.05,...
                                           'ChangeRatio_TF',           0.05,...
                                           'ChangeRatio_zF',           0.05);
% Set up the P2_SimParam data structure. Be careful with test number
handles.P2_SimParam_DefaultValues = struct('TestId',                   '01',...
                                           'TestDescription',          '',...
                                           'SimTime',                  50,...
                                           'ActivateDisturbances_z',   1,...
                                           'DisturbanceTime_z',        10,...
                                           'DisturbanceType_z',        1,...
                                           'DisturbanceDuration_z',    1,...
                                           'PulseDuration_z',          0.5,...
                                           'DisturbanceSize_z',        20,...
                                           'ActivateDisturbances_T',   0,...
                                           'DisturbanceTime_T',        10,...
                                           'DisturbanceType_T',        1,...
                                           'DisturbanceDuration_T',    1,...
                                           'PulseDuration_T',          0.5,...
                                           'DisturbanceSize_T',        20,...
                                           'ActivateDisturbances_F',   0,...
                                           'DisturbanceTime_F',        10,...
                                           'DisturbanceType_F',        1,...
                                           'DisturbanceDuration_F',    1,...
                                           'PulseDuration_F',          0.5,...
                                           'DisturbanceSize_F',        20,...
                                           'Activate_PI_Failure_xB',   0,...
                                           'Time_PI_Failure_xB',       10,...
                                           'Activate_PI_Failure_yD',   0,...
                                           'Time_PI_Failure_yD',       10,...
                                           'AddSecondOP',              0,...
                                           'TimeChangeOperatingPoint', 10,...
                                           'OP_2',                     1,...
                                           'xBs_2',                    0.01,...
                                           'yDs_2',                    0.99);
guidata(hObject, handles);



function txtDisturbanceSize_z_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceSize_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceSize_z as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceSize_z as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceSize_z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceSize_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtDisturbanceDuration_z_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceDuration_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceDuration_z as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceDuration_z as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceDuration_z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceDuration_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtDisturbanceSize_T_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceSize_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceSize_T as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceSize_T as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceSize_T_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceSize_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtDisturbanceDuration_T_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceDuration_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceDuration_T as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceDuration_T as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceDuration_T_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceDuration_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtDisturbanceSize_F_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceSize_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceSize_F as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceSize_F as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceSize_F_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceSize_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtDisturbanceDuration_F_Callback(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceDuration_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtDisturbanceDuration_F as text
%        str2double(get(hObject,'String')) returns contents of txtDisturbanceDuration_F as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtDisturbanceDuration_F_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtDisturbanceDuration_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function wave = CreateDisturbanceSignal(tSample,time,type,initialValue,size,duration,pulseDuration,feedSignal)
%The default value is a typical feed signal that will be replaced by the
%disturbance signal at a given time ...
tSignal = feedSignal(:,1)';
wsSignal = feedSignal(:,2);
maxValue = initialValue * (1+size/100);
switch type
    case 1 %Spike
        tMax = time+duration/2;
        % ascendent
        tAsc = time:tSample:tMax;
        ind1 = fix(time/tSample)+1;
        ind2 = fix(tMax/tSample)+1;
        pte = ((maxValue-initialValue)/(duration/2));
        r = initialValue + pte*(tAsc-time);
        if ind2-ind1+1 > length(r)
            ind2 = length(r)+ind1-1;
        end
        for i=ind1:1:ind2
            wsSignal(i) = r(i-ind1+1);
        end
        % descendent
        tDesc = tMax:tSample:(tMax+duration/2);
        ind1 = fix(tMax/tSample)+1;
        ind2 = fix((tMax+duration/2)/tSample)+1;
        r = maxValue - pte*(tDesc-tMax);
        if ind2-ind1+1 > length(r)
            ind2 = length(r)+ind1-1;
        end
        for i=ind1:1:ind2
            wsSignal(i) = r(i-ind1+1);
        end
    case 2 %Ramp
        tMax = time+duration;
        tAsc = time:tSample:tMax;
        ind1 = fix(time/tSample)+1;
        ind2 = fix(tMax/tSample)+1;
        pte = (maxValue-initialValue)/duration;
        r = initialValue + pte*(tAsc-time);
        if ind2-ind1+1 > length(r)
            ind2 = length(r)+ind1-1;
        end
        for i=ind1:1:ind2
            wsSignal(i) = r(i-ind1+1);
        end
        wsSignal(ind2+1:end) = maxValue;        
    case 3 %Pulse
        % pulseDuration: duration of the steady part of the pulse
        tRamp = (duration-pulseDuration)/2;
        % Ascending part
        tAscEnd = time + tRamp;
        tAsc = time:tSample:tAscEnd;        
        ind1 = fix(time/tSample)+1;
        ind2 = fix(tAscEnd/tSample)+1;
        pte = ((maxValue-initialValue)/tRamp);
        r = initialValue + pte*(tAsc-time);
        if ind2-ind1+1 > length(r)
            ind2 = length(r)+ind1-1;
        end
        for i=ind1:1:ind2
            wsSignal(i) = r(i-ind1+1);
        end
        % Steady part
        tSteadyEnd = tAscEnd + pulseDuration;
        tSteady = tAscEnd:tSample:tSteadyEnd;
        ind1 = fix(tAscEnd/tSample)+1;
        ind2 = fix(tSteadyEnd/tSample)+1;
        wsSignal(ind1:ind2) = maxValue;
        % Descending part
        tDescEnd = tSteadyEnd + tRamp;
        tDesc = tSteadyEnd:tSample:tDescEnd;
        ind1 = fix(tSteadyEnd/tSample)+1;
        ind2 = fix(tDescEnd/tSample)+1;
        r = maxValue - pte*(tDesc-tSteadyEnd);
        if ind2-ind1+1 > length(r)
            ind2 = length(r)+ind1-1;
        end
        for i=ind1:1:ind2
            wsSignal(i) = r(i-ind1+1);
        end
end

wave = [tSignal' wsSignal];



function txtPulseDuration_z_Callback(hObject, eventdata, handles)
% hObject    handle to txtPulseDuration_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtPulseDuration_z as text
%        str2double(get(hObject,'String')) returns contents of txtPulseDuration_z as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtPulseDuration_z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtPulseDuration_z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtPulseDuration_T_Callback(hObject, eventdata, handles)
% hObject    handle to txtPulseDuration_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtPulseDuration_T as text
%        str2double(get(hObject,'String')) returns contents of txtPulseDuration_T as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtPulseDuration_T_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtPulseDuration_T (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtPulseDuration_F_Callback(hObject, eventdata, handles)
% hObject    handle to txtPulseDuration_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtPulseDuration_F as text
%        str2double(get(hObject,'String')) returns contents of txtPulseDuration_F as a double
SaveParam(hObject,handles,2);



% --- Executes during object creation, after setting all properties.
function txtPulseDuration_F_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtPulseDuration_F (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function SaveParam(hObject,handles,phase)

if phase==1
    % Set up the P1_SimParam data structure
    SimParam = struct('BenchmarkName',            get(handles.txtBenchmarkName,'string'),...
                      'BenchmarkDesc',            get(handles.txtBenchmarkDesc,'string'),...
                      'SimTime',                  str2num(get(handles.txtSimTime,'string')),...
                      'SampleTime',               str2double(get(handles.txtSampleTime,'string')),...
                      'AddNoise',                 get(handles.chkNoise,'value'),...
                      'OP_1',                     get(handles.cmbFirstOP,'value'),...
                      'xBs_1',                    str2double(get(handles.txtXBs_1,'string')),...
                      'yDs_1',                    str2double(get(handles.txtYDs_1,'string')),...
                      'EnableFeedChanges',        get(handles.chkEnableFeedChanges,'value'),...
                      'ChangeRatio_Period',       str2double(get(handles.txtChangeRatio_Period,'string')),...
                      'ChangeRatio_FV',           str2double(get(handles.txtChangeRatio_F,'string'))/100,...
                      'ChangeRatio_TF',           str2double(get(handles.txtChangeRatio_T,'string'))/100,...
                      'ChangeRatio_zF',           str2double(get(handles.txtChangeRatio_z,'string'))/100);
    % Store the new param
    handles.P1_SimParam = SimParam;
else
    % Set up the P2_SimParam data structure. Be careful with test number
    SimParam = struct('TestId',                   str2num(get(handles.txtTestId,'string')),...
                      'TestDescription',          get(handles.txtTestDescription,'string'),...
                      'SimTime',                  str2num(get(handles.txtSimTimePhaseII,'string')),...
                      'ActivateDisturbances_z',   get(handles.chkActDisturb_z,'value'),...
                      'DisturbanceTime_z',        str2double(get(handles.txtDisturbanceTime_z,'string')),...
                      'DisturbanceType_z',        get(handles.cmbDisturbanceType_z,'value'),...
                      'DisturbanceSize_z',        get(handles.txtDisturbanceSize_z,'string'),...
                      'DisturbanceDuration_z',    get(handles.txtDisturbanceDuration_z,'string'),...
                      'PulseDuration_z',          get(handles.txtPulseDuration_z,'string'),...
                      'ActivateDisturbances_T',   get(handles.chkActDisturb_T,'value'),...        
                      'DisturbanceTime_T',        str2double(get(handles.txtDisturbanceTime_T,'string')),...
                      'DisturbanceType_T',        get(handles.cmbDisturbanceType_T,'value'),...
                      'DisturbanceSize_T',        get(handles.txtDisturbanceSize_T,'string'),...
                      'DisturbanceDuration_T',    get(handles.txtDisturbanceDuration_T,'string'),...
                      'PulseDuration_T',          get(handles.txtPulseDuration_T,'string'),...
                      'ActivateDisturbances_F',   get(handles.chkActDisturb_F,'value'),...    
                      'DisturbanceTime_F',        str2double(get(handles.txtDisturbanceTime_F,'string')),...
                      'DisturbanceType_F',        get(handles.cmbDisturbanceType_F,'value'),...
                      'DisturbanceSize_F',        get(handles.txtDisturbanceSize_F,'string'),...
                      'DisturbanceDuration_F',    get(handles.txtDisturbanceDuration_F,'string'),...
                      'PulseDuration_F',          get(handles.txtPulseDuration_F,'string'),...
                      'Activate_PI_Failure_xB',   get(handles.chkActFailure_xB,'value'),...
                      'Time_PI_Failure_xB',       str2double(get(handles.txtTimeFailure_xB,'string')) ,...
                      'Activate_PI_Failure_yD',   get(handles.chkActFailure_yD,'value')     ,...
                      'Time_PI_Failure_yD',       str2double(get(handles.txtTimeFailure_yD,'string')) ,...
                      'AddSecondOP',              get(handles.chkAddSecondOP,'value'),...
                      'TimeChangeOperatingPoint', get(handles.txtTimeChangeOperatingPoint,'string'),...
                      'OP_2',                     get(handles.cmbSecondOP,'value'),...
                      'xBs_2',                    str2double(get(handles.txtXBs_2,'string')),...
                      'yDs_2',                    str2double(get(handles.txtYDs_2,'string')));
	% Store the new param
    sTestId = get(handles.txtTestId,'string');
    sEval = ['handles.P2_SimParam_' sTestId ' = SimParam;'];
    eval(sEval);
end

guidata(handles.MSPC_main, handles);
if isfield(handles,'mTree')
    set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}); %update handles struct when calling NodeSelectedCallback
end


function [phase,sType,sTestId] = GetPhase(handles)
tree = handles.mTree;
nodes = tree.getSelectedNodes;
node = nodes(1);
sValue = node.getValue;
sPhase = sValue(1:2);
if strcmp(sPhase,'P1')
    phase=1;
    sType = sValue(3:5);
    sTestId = [];
elseif strcmp(sPhase,'P2') && (size(sValue,2)>5)
    phase=2;
    sType = sValue(3:5);
    sTestId = sValue(6:end);
else
    phase=0;
    sType = [];
    sTestId = [];
end


% --------------------------------------------------------------------
function mnuPhaseI_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseI (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function mnuPhaseIIPlotResults_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIIPlotResults (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

mnuPhaseIPlotResults_Callback(hObject, eventdata, handles);



function txtSimTimePhaseII_Callback(hObject, eventdata, handles)
% hObject    handle to txtSimTimePhaseII (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtSimTimePhaseII as text
%        str2double(get(hObject,'String')) returns contents of txtSimTimePhaseII as a double


% --- Executes during object creation, after setting all properties.
function txtSimTimePhaseII_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtSimTimePhaseII (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function A = PlotVariance(L,bPlot,bType)
%% Variance explained
pVar = 100*L./sum(L); % percentage of variance explained by each PC
A = find(cumsum(pVar)>=90,1,'first'); % number of PCs that explain >90% of variance
sTitle = 'Phase I. PCA results. Variance explained by PCs';
switch bType
    case 2
        sTitle = [sTitle ' (full dataset)'];
    case 3
        sTitle = [sTitle ' (NOC dataset)'];
end
if bPlot
    MSPC_variance('title',sTitle,...
                  'A',A,...
                  'pVar',pVar);
end

% --------------------------------------------------------------------

function mnuPhaseIVariance_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIVariance (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%% Variance explained
if ~check_errors('handles', handles, 'sType', 'computePCA')
    return;
end
PlotVariance(handles.P1_PCAResults.L,1,1);


% --- Executes on button press in chkEnableFeedChanges.
function chkEnableFeedChanges_Callback(hObject, eventdata, handles)
% hObject    handle to chkEnableFeedChanges (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of chkEnableFeedChanges
if get(handles.chkEnableFeedChanges,'value')==1
    set(handles.txtChangeRatio_Period,'enable','on');
    set(handles.txtChangeRatio_F,'enable','on');
    set(handles.txtChangeRatio_T,'enable','on');
    set(handles.txtChangeRatio_z,'enable','on');
else
    set(handles.txtChangeRatio_Period,'enable','off');
    set(handles.txtChangeRatio_F,'enable','off');
    set(handles.txtChangeRatio_T,'enable','off');
    set(handles.txtChangeRatio_z,'enable','off');
end
SaveParam(hObject,handles,1);



function txtChangeRatio_Period_Callback(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_Period (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtChangeRatio_Period as text
%        str2double(get(hObject,'String')) returns contents of txtChangeRatio_Period as a double
SaveParam(hObject,handles,1);


% --- Executes during object creation, after setting all properties.
function txtChangeRatio_Period_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtChangeRatio_Period (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function wave = CreateFeedSignal(tSim,tSample,type,initialValue,ChangeRatio,ChangePeriod)
% Change is computed from the last value, but the new value cannot
% exceed n times the maximum ChangeRatio
nTimesRatio = 1;
maxChange = initialValue+initialValue*(nTimesRatio*ChangeRatio/100);
minChange = 2*initialValue-maxChange;
tSignal = 0:tSample:tSim;
wsSignal = initialValue * ones(length(tSignal),1);
lastValue = initialValue;
for t=0:ChangePeriod:tSim
    nextValue = initialValue+maxChange;%assures entering in the loop
    while nextValue > maxChange || nextValue < minChange
        n = -ChangeRatio + (2*ChangeRatio*rand(1));
        nextValue = lastValue * (1+n/100);
    end
    switch type
        case 2 %Ramp
            tMax = t+ChangePeriod;
            tAsc = t:tSample:tMax;
            ind1 = fix(t/tSample)+1;
            ind2 = fix(tMax/tSample)+1;
            pte = (nextValue-lastValue)/ChangePeriod;
            r = lastValue + pte*(tAsc-t);
            if ind2-ind1+1 > length(r)
                ind2 = length(r)+ind1-1;
            end
            for i=ind1:1:ind2
                wsSignal(i) = r(i-ind1+1);
            end
            wsSignal(ind2+1:end) = nextValue;
            lastValue = nextValue;
        case 3 %Half ramp: ends with a steady part
            tMax = t+ChangePeriod/2;
            tAsc = t:tSample:tMax;
            ind1 = fix(t/tSample)+1;
            ind2 = fix(tMax/tSample)+1;
            pte = (nextValue-lastValue)/ChangePeriod;
            r = lastValue + pte*(tAsc-t);
            if ind2-ind1+1 > length(r)
                ind2 = length(r)+ind1-1;
            end
            for i=ind1:1:ind2
                wsSignal(i) = r(i-ind1+1);
            end
            %Steady part ...
            ind1 = fix((t+ChangePeriod/2)/tSample)+1;
            ind2 = fix((t+ChangePeriod)/tSample)+1;
            for i=ind1:1:ind2
                wsSignal(i) = nextValue;
            end
            wsSignal(ind2+1:end) = nextValue;
            lastValue = nextValue;
    end
end

wave = [tSignal' wsSignal(1:size(tSignal',1))];


% --- Executes during object creation, after setting all properties.
function MSPC_main_CreateFcn(hObject, eventdata, handles)
% hObject    handle to MSPC_main (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --------------------------------------------------------------------
function mnuPhaseIAutoModel_Callback(hObject, eventdata, handles)
% hObject    handle to mnuPhaseIAutoModel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Performs a cross-validation routine to search for the best model for
% process monitoring. An initial large dataset of process variables under
% NOC is divided into two datasets: 2/3 are used for searching and 1/3 for
% model validation. The methodology is the following:
%     Take 10 sets of N observations from the searching dataset. N is low,
%     lets say 1% of the total number of observations of the searching
%     dataset.
%     Compute

if ~check_errors('handles', handles, 'sType', 'phaseI_data')
    return;
end

[Z,vnames] = construct_Z(handles.P1_SimResults,0,0);
n = size(Z,1);
alpha = 0.05;
rErrorTol = 0.1;

%Full validation ...
Zsearch = Z;
Zvalid = Z;

results = [];
%    Column 1 --> observation id
%    Column 2 --> model size
%    Column 3 --> percentage of points out-of-control SPE chart
%    Column 4 --> percentage of points out-of-control T2 chart

nPSearch = size(Zsearch,1);
idOpt = -1;
idObs = 0;
idTM = 0;
nRep = 10;
nPModelSearch = 0;
percent = 0;
cut_perc = 90;
nRes = 0;
fSim = figure('Name','Automodel selection');
while nRes==0
    nPModelSearch_old = nPModelSearch;
    while percent<=cut_perc && (nPModelSearch<10 || nPModelSearch==nPModelSearch_old)
        percent = percent + 0.1;
        nPModelSearch = round(percent * nPSearch/100);
    end
    if percent>cut_perc && nPModelSearch<10
        nRes = -1;
        break;
    end
    ZmodelSearch = zeros(nPModelSearch,size(Zsearch,2),nRep);
    for i=1:nRep
        %Random nPoints sampling ...
        indUnique = randperm(nPSearch); %returns a row vector containing nPModelSearch unique integers selected randomly from 1 to nPSearch inclusive.
        indUnique = indUnique(1:nPModelSearch);
        ZmodelSearch_2D = Zsearch(indUnique,:);
        ZmodelSearch(:,:,i) = ZmodelSearch_2D(:,:);
        [percSPEOut_05,percT2Out_05] = CV_PCA(0.05,ZmodelSearch_2D,Zvalid);%returns percentage of points that are out-of-control
        [percSPEOut_01,percT2Out_01] = CV_PCA(0.01,ZmodelSearch_2D,Zvalid);%returns percentage of points that are out-of-control
        %Store results ...
        idObs = idObs+1;
        results(idObs,1) = idObs;
        results(idObs,2) = nPModelSearch;
        results(idObs,3) = percSPEOut_05;
        results(idObs,4) = percT2Out_05;
        results(idObs,5) = percSPEOut_01;
        results(idObs,6) = percT2Out_01;
    end
    figure(fSim);
    subplot(1,2,1);
    plot(results(:,2),results(:,3),'.');
  	subplot(1,2,2);
    plot(results(:,2),results(:,5),'.');
    drawnow;
    %Convergence criteria 1
    nSize = size(results,1);
    if nSize >= 2*nRep
        %Compares last two groups ...
        G2 = results(nSize-nRep+1:end,:);
        if ttest(G2(:,3),0.05*100,0.05,'right')==0 && ttest(G2(:,5),0.01*100,0.05,'right')==0
             if idOpt==-1
                idOpt = find(G2(:,3)==min(G2(:,3)));
                Zoptimum = ZmodelSearch(:,:,idOpt);
                Zoptimum = reshape(Zoptimum,size(Zoptimum,1),size(Zoptimum,2));
                handles.P1_SimResults.Zoptimum = Zoptimum;
                handles.P1_SimResults.VariableNames = vnames;
                guidata(hObject, handles);
                idOpt = G2(idOpt,1);
                nRes = 1;
             end
        end
    end
%     % Forces to plot at last 5% of total points
%     if percent>5
%         if idOpt~=-1
%             cont = false;
%         end
%     end
    if percent>cut_perc
        % Doesn´t converge ?
        nRes = -2;
    end
end
close(fSim);
drawnow;
if nRes<0
	msgbox('There aren´t enought data for this benchmark to perform automodel selection. Please, increase simulation time.','Automodel selection','warn');
    return;
end
fRes = figure('Name','Automodel selection');
%Plot results
plot(results(:,2),results(:,3),'.',results(idOpt,2),results(idOpt,3),'*r');
line([results(1,2) results(end,2)],[5 5],'Color','r','LineStyle','--','LineWidth',1)
xlabel('nP_M_o_d_e_l');
ylabel('% out-of-control');

%Statistics grouped by nPModel ...
fStats = figure('Name','Statistics by model size');
[testMean,testMean_ci,testStd,g] = grpstats(results(:,3),results(:,2),{'mean','meanci','std','gname'});
n = length(testMean);
%Plot variance
figure(fStats);
bar(testStd);
xlabel('nPModel')
ylabel('Standard deviation')
set(gca,'xtick',1:n,'xticklabel',g);

%Plot mean and confidence interval
fMean = figure('Name','Mean and confidence interval');
errorbar((1:n)',testMean,testMean_ci(:,2)+testMean);
line([0 n],[5 5],'Color','r','LineStyle','--','LineWidth',1);
figure(fStats);
set(gca,'xtick',1:2:n,'xticklabel',g(1:2:n));
xlabel('nP_M_o_d_e_l')
ylabel('mean')
title('95% confidence intervals');
drawnow;

% Compute PCA automatically
mnuPhaseIComputePCA_Callback(handles.MSPC_main, eventdata, handles);


function [nSPE_out,nT2_out] = CV_PCA(alpha,Z,Znew)
% Returns the number of points that are out of control limits.

%% Compute PCA through SVD ...
[N K] = size (Z); % N observations, K variables
Zmean = mean(Z);
Zstd = std(Z);
% Standardized X matrix ...
X = (Z - repmat(Zmean,[N 1])) ./ repmat(Zstd,[N 1]);
% SVD ...
[U,S,V] = svd(X);
%Scores
T = U * S;
%Loadings
P = V;
%Eigenvalues of the covariance matrix of X
L = (diag(S) .* diag(S))/(N-1);

%% Variance explained
pVar = 100*L./sum(L); % percentage of variance explained by each PC
A = find(cumsum(pVar)>=90,1,'first'); % number of PCs that explain >90% of variance

%% Residuals
%Computing residuals from scores and loadings matrices:
Xstar = T(:,1:A) * P(:,1:A)';
E = X - Xstar;

%% Hotelling's T2
% t2, is Hotelling's T2, a statistical measure of the multivariate distance of each observation from the center of the data set.
% This is an analytical way to find the most extreme points in the data.

% Hotelling T2 computation for each observation:
Tsquared = zeros(1,N);
for i=1:N;
    for a = 1:A;
        Tsquared(i) = Tsquared(i) + T(i,a)^2 / L(a);
    end;
end;
% UCL for Hotelling T2 at significance level alpha (Phase I)
F = finv(1-alpha,A,N-A-1);
B = (A/(N-A-1))*F/(1+(A/(N-A-1))*F);
UCL_T2 = (N-1)^2*B/N;


%% Sum of squared prediction errors
SPE = diag(E()*E()');
% UCL for SPE at significance level alpha (Phase I)
SPEmean = mean(SPE);
SPEvar = var(SPE);
ChiSquared = chi2inv(1-alpha,2*SPEmean^2/SPEvar);
SPE_UCL = SPEvar*ChiSquared/(2*SPEmean);

%% Exploit model ...
% Scale new data
[Nnew Knew] = size (Znew); % Knew must be equal to K, i.e., the number of variables is the same
% Standardized X (phase II)
Xnew = (Znew - repmat(Zmean,[Nnew 1])) ./ repmat(Zstd,[Nnew 1]);
% Scores for the new observations
Tnew = Xnew * P;
% Model prediction for new observations
Xstarnew = Tnew(:,1:A) * P(:,1:A)';
% Prediction error for new observations
Enew = Xnew - Xstarnew;

%% Phase II. Hotelling's T2
TsquaredNew = zeros(1,Nnew);
for i=1:Nnew;
    for a = 1:A;
        TsquaredNew(i) = TsquaredNew(i) + Tnew(i,a)^2 / L(a);
    end;
end;
ind = find(TsquaredNew > UCL_T2);
nT2_out = size(ind,2)*100/size(TsquaredNew,2);

%% Phase II. SPE
EnewSquared = Enew() .* Enew(); %son los e^2 (contribuciones a SPE) de cada variable para cada observación
SPEnew = sum(EnewSquared,2); %suma las filas, las contribuciones de todas las variables en cada observación

%Points out of control in SPE chart
ind = find(SPEnew > SPE_UCL);
nSPE_out = size(ind,1)*100/size(SPEnew,1);


function res = check_errors(varargin)
res = 0;
% Handles
nInput = find(strcmp(varargin, 'handles'));
handles = varargin{nInput+1};
% Error type to check
nInput = find(strcmp(varargin, 'sType'));
sType = varargin{nInput+1};
% Test id (optional)
sTestId = [];
nInput = find(strcmp(varargin, 'sTestId'));
if nInput 
    sTestId = varargin{nInput+1};
end

if strcmp(sType,'phaseI_data') || strcmp(sType,'computePCA')
    if ~isfield(handles,'P1_SimResults')
        msgbox(['There are no data for this benchmark. Please, first run simulation to get some data ' ... 
                ' (menu "Phase I >> Simulation >> Run simulation")'],'Compute PCA','warn');
        return;
    end
end
if strcmp(sType,'computePCA')
    if ~isfield(handles,'P1_PCAResults');
        msgbox('There is no PCA model for this benchmark. Please, first run menu option "Phase II >> PCA >> Automodel selection" or "Phase II >> PCA >> Compute PCA".',['Test ' sTestId],'warn');
        return;
    end
end
if strcmp(sType,'phaseII_data') || strcmp(sType,'exploitPCA')
    if ~isfield(handles,['P2_SimResults_' sTestId ]);
        msgbox(['There are no data for this test. Please, first run simulation to get some data' ... 
                ' (menu "Phase II >> Simulation >> Run simulation")'],['Test ' sTestId],'warn');
        return;
    end
end
if strcmp(sType,'exploitPCA')
    if ~isfield(handles,['P2_PCAResults_' sTestId ]);
        msgbox('There are no PCA results for this test. Please, first run menu option "Phase II >> PCA >> Model exploitation".',['Test ' sTestId],'warn');
        return;
    end
end

res = 1;



function txtExternalData_Callback(hObject, eventdata, handles)
% hObject    handle to txtExternalData (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtExternalData as text
%        str2double(get(hObject,'String')) returns contents of txtExternalData as a double


% --- Executes during object creation, after setting all properties.
function txtExternalData_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtExternalData (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function txtExtTestDesc_Callback(hObject, eventdata, handles)
% hObject    handle to txtExtTestDesc (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of txtExtTestDesc as text
%        str2double(get(hObject,'String')) returns contents of txtExtTestDesc as a double
sTestId = get(handles.txtTestId,'string');
sEval = ['handles.P2_SimParam_' sTestId '.TestDescription = ''' get(handles.txtExtTestDesc,'String') ''';'];
eval(sEval);
guidata(handles.MSPC_main, handles);


% --- Executes during object creation, after setting all properties.
function txtExtTestDesc_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txtExtTestDesc (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end